PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.63
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.63
51.1.86 51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 All 40 releases
king-addons / includes / widgets / Parallax_Depth_Cards / Parallax_Depth_Cards.php

Parallax_Depth_Cards.php in King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder 51.1.63, at includes/widgets/Parallax_Depth_Cards/Parallax_Depth_Cards.php

1,849 lines 62.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Parallax Depth Cards Widget (Free).
4 *
5 * @package King_Addons
6 */
7
8 namespace King_Addons;
9
10 use Elementor\Controls_Manager;
11 use Elementor\Group_Control_Background;
12 use Elementor\Group_Control_Border;
13 use Elementor\Group_Control_Box_Shadow;
14 use Elementor\Group_Control_Image_Size;
15 use Elementor\Group_Control_Typography;
16 use Elementor\Icons_Manager;
17 use Elementor\Repeater;
18 use Elementor\Utils;
19 use Elementor\Widget_Base;
20
21 if (!defined('ABSPATH')) {
22 exit;
23 }
24
25 /**
26 * Parallax depth cards widget.
27 */
28 class Parallax_Depth_Cards extends Widget_Base
29 {
30 /**
31 * Widget slug.
32 *
33 * @return string
34 */
35 public function get_name(): string
36 {
37 return 'king-addons-parallax-depth-cards';
38 }
39
40 /**
41 * Widget title.
42 *
43 * @return string
44 */
45 public function get_title(): string
46 {
47 return esc_html__('Parallax Depth Cards', 'king-addons');
48 }
49
50 /**
51 * Widget icon.
52 *
53 * @return string
54 */
55 public function get_icon(): string
56 {
57 return 'king-addons-icon king-addons-parallax-depth-cards';
58 }
59
60 /**
61 * Style dependencies.
62 *
63 * @return array<int, string>
64 */
65 public function get_style_depends(): array
66 {
67 return [
68 KING_ADDONS_ASSETS_UNIQUE_KEY . '-parallax-depth-cards-style',
69 'elementor-icons-fa-solid',
70 'elementor-icons-fa-regular',
71 'elementor-icons-fa-brands',
72 ];
73 }
74
75 /**
76 * Script dependencies.
77 *
78 * @return array<int, string>
79 */
80 public function get_script_depends(): array
81 {
82 return [
83 KING_ADDONS_ASSETS_UNIQUE_KEY . '-parallax-depth-cards-script',
84 ];
85 }
86
87 /**
88 * Widget categories.
89 *
90 * @return array<int, string>
91 */
92 public function get_categories(): array
93 {
94 return ['king-addons'];
95 }
96
97 /**
98 * Widget keywords.
99 *
100 * @return array<int, string>
101 */
102 public function get_keywords(): array
103 {
104 return ['parallax', 'depth', 'cards', 'tilt', 'hover', '3d', 'interactive'];
105 }
106
107 public function get_custom_help_url()
108 {
109 return 'mailto:[email protected]?subject=Bug Report - King Addons&body=Please describe the issue';
110 }
111
112 /**
113 * Register widget controls.
114 *
115 * @return void
116 */
117 public function register_controls(): void
118 {
119 $this->register_layout_controls();
120 $this->register_cards_controls();
121 $this->register_single_card_controls();
122 $this->register_interaction_controls();
123 $this->register_style_controls();
124 $this->register_pro_notice_controls();
125 }
126
127 /**
128 * Render widget output.
129 *
130 * @return void
131 */
132 public function render(): void
133 {
134 $settings = $this->get_settings_for_display();
135 $mode = $settings['kng_pdc_mode'] ?? 'cards';
136
137 if ($mode === 'single') {
138 $cards = [$this->get_single_card_data($settings)];
139 } else {
140 $cards = $settings['kng_pdc_cards'] ?? [];
141 }
142
143 if (empty($cards)) {
144 return;
145 }
146
147 $align = $settings['kng_pdc_content_align'] ?? 'left';
148 $valign = $settings['kng_pdc_content_v_align'] ?? 'top';
149 $height_mode = $settings['kng_pdc_card_height_mode'] ?? 'auto';
150
151 $wrapper_classes = [
152 'king-addons-parallax-depth-cards',
153 'king-addons-parallax-depth-cards--mode-' . sanitize_html_class($mode),
154 'king-addons-parallax-depth-cards--align-' . sanitize_html_class($align),
155 'king-addons-parallax-depth-cards--valign-' . sanitize_html_class($valign),
156 'king-addons-parallax-depth-cards--height-' . sanitize_html_class($height_mode),
157 ];
158
159 $enable_tilt = ($settings['kng_pdc_enable_tilt'] ?? 'yes') === 'yes';
160 $enable_parallax = ($settings['kng_pdc_enable_parallax'] ?? 'yes') === 'yes';
161 $trigger = sanitize_key($settings['kng_pdc_trigger'] ?? 'hover');
162 $reduce_motion = ($settings['kng_pdc_reduce_motion'] ?? 'yes') === 'yes';
163 $disable_touch = ($settings['kng_pdc_disable_touch'] ?? 'yes') === 'yes';
164
165 $intensity = $this->get_control_number($settings['kng_pdc_intensity'] ?? 60, 60);
166 $max_tilt = $this->get_control_number($settings['kng_pdc_max_tilt'] ?? 12, 12);
167 $depth_strength = $this->get_control_number($settings['kng_pdc_depth_strength'] ?? 18, 18);
168 $smoothing = $this->get_control_number($settings['kng_pdc_smoothing'] ?? 0.12, 0.12);
169 $reset_duration = $this->get_control_number($settings['kng_pdc_reset_duration'] ?? 350, 350);
170
171 $depths = [
172 'bg' => $this->get_control_number($settings['kng_pdc_depth_bg'] ?? 0.2, 0.2),
173 'media' => $this->get_control_number($settings['kng_pdc_depth_media'] ?? 0.35, 0.35),
174 'content' => $this->get_control_number($settings['kng_pdc_depth_content'] ?? 0.5, 0.5),
175 ];
176
177 $wrapper_attributes = [
178 'class' => implode(' ', $wrapper_classes),
179 'data-tilt' => $enable_tilt ? 'yes' : 'no',
180 'data-parallax' => $enable_parallax ? 'yes' : 'no',
181 'data-intensity' => (string) $intensity,
182 'data-max-tilt' => (string) $max_tilt,
183 'data-depth-strength' => (string) $depth_strength,
184 'data-smoothing' => (string) $smoothing,
185 'data-reset-duration' => (string) $reset_duration,
186 'data-trigger' => $trigger,
187 'data-reduce-motion' => $reduce_motion ? 'yes' : 'no',
188 'data-disable-touch' => $disable_touch ? 'yes' : 'no',
189 ];
190
191 ?>
192 <div <?php echo $this->render_attribute_string($wrapper_attributes); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
193 <div class="king-addons-parallax-depth-cards__grid">
194 <?php foreach ($cards as $card) : ?>
195 <?php $this->render_card($settings, $card, $depths); ?>
196 <?php endforeach; ?>
197 </div>
198 </div>
199 <?php
200 }
201
202 /**
203 * Register layout controls.
204 *
205 * @return void
206 */
207 protected function register_layout_controls(): void
208 {
209 $this->start_controls_section(
210 'kng_pdc_layout_section',
211 [
212 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Layout', 'king-addons'),
213 'tab' => Controls_Manager::TAB_CONTENT,
214 ]
215 );
216
217 $this->add_control(
218 'kng_pdc_mode',
219 [
220 'label' => esc_html__('Mode', 'king-addons'),
221 'type' => Controls_Manager::SELECT,
222 'options' => [
223 'cards' => esc_html__('Cards (Repeater)', 'king-addons'),
224 'single' => esc_html__('Single Card', 'king-addons'),
225 ],
226 'default' => 'cards',
227 ]
228 );
229
230 $this->add_responsive_control(
231 'kng_pdc_columns',
232 [
233 'label' => esc_html__('Columns', 'king-addons'),
234 'type' => Controls_Manager::NUMBER,
235 'min' => 1,
236 'max' => 6,
237 'step' => 1,
238 'desktop_default' => 3,
239 'tablet_default' => 2,
240 'mobile_default' => 1,
241 'selectors' => [
242 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-cols: {{SIZE}};',
243 ],
244 'condition' => [
245 'kng_pdc_mode' => 'cards',
246 ],
247 ]
248 );
249
250 $this->add_responsive_control(
251 'kng_pdc_column_gap',
252 [
253 'label' => esc_html__('Column Gap', 'king-addons'),
254 'type' => Controls_Manager::SLIDER,
255 'size_units' => ['px', 'em', 'rem'],
256 'range' => [
257 'px' => ['min' => 0, 'max' => 80],
258 'em' => ['min' => 0, 'max' => 4],
259 'rem' => ['min' => 0, 'max' => 4],
260 ],
261 'default' => [
262 'size' => 24,
263 'unit' => 'px',
264 ],
265 'selectors' => [
266 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-col-gap: {{SIZE}}{{UNIT}};',
267 ],
268 'condition' => [
269 'kng_pdc_mode' => 'cards',
270 ],
271 ]
272 );
273
274 $this->add_responsive_control(
275 'kng_pdc_row_gap',
276 [
277 'label' => esc_html__('Row Gap', 'king-addons'),
278 'type' => Controls_Manager::SLIDER,
279 'size_units' => ['px', 'em', 'rem'],
280 'range' => [
281 'px' => ['min' => 0, 'max' => 80],
282 'em' => ['min' => 0, 'max' => 4],
283 'rem' => ['min' => 0, 'max' => 4],
284 ],
285 'default' => [
286 'size' => 24,
287 'unit' => 'px',
288 ],
289 'selectors' => [
290 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-row-gap: {{SIZE}}{{UNIT}};',
291 ],
292 'condition' => [
293 'kng_pdc_mode' => 'cards',
294 ],
295 ]
296 );
297
298 $this->add_control(
299 'kng_pdc_card_height_mode',
300 [
301 'label' => esc_html__('Card Height', 'king-addons'),
302 'type' => Controls_Manager::SELECT,
303 'options' => [
304 'auto' => esc_html__('Auto', 'king-addons'),
305 'min' => esc_html__('Min Height', 'king-addons'),
306 ],
307 'default' => 'auto',
308 ]
309 );
310
311 $this->add_responsive_control(
312 'kng_pdc_card_min_height',
313 [
314 'label' => esc_html__('Card Min Height', 'king-addons'),
315 'type' => Controls_Manager::SLIDER,
316 'size_units' => ['px', 'em', 'rem'],
317 'range' => [
318 'px' => ['min' => 160, 'max' => 600],
319 'em' => ['min' => 10, 'max' => 40],
320 'rem' => ['min' => 10, 'max' => 40],
321 ],
322 'selectors' => [
323 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-card-min-height: {{SIZE}}{{UNIT}};',
324 ],
325 'condition' => [
326 'kng_pdc_card_height_mode' => 'min',
327 ],
328 ]
329 );
330
331 $this->add_control(
332 'kng_pdc_content_align',
333 [
334 'label' => esc_html__('Content Alignment', 'king-addons'),
335 'type' => Controls_Manager::SELECT,
336 'options' => [
337 'left' => esc_html__('Left', 'king-addons'),
338 'center' => esc_html__('Center', 'king-addons'),
339 'right' => esc_html__('Right', 'king-addons'),
340 ],
341 'default' => 'left',
342 ]
343 );
344
345 $this->add_control(
346 'kng_pdc_content_v_align',
347 [
348 'label' => esc_html__('Vertical Alignment', 'king-addons'),
349 'type' => Controls_Manager::SELECT,
350 'options' => [
351 'top' => esc_html__('Top', 'king-addons'),
352 'center' => esc_html__('Center', 'king-addons'),
353 'bottom' => esc_html__('Bottom', 'king-addons'),
354 ],
355 'default' => 'top',
356 ]
357 );
358
359 $this->add_control(
360 'kng_pdc_title_tag',
361 [
362 'label' => esc_html__('Title HTML Tag', 'king-addons'),
363 'type' => Controls_Manager::SELECT,
364 'options' => [
365 'h1' => 'H1',
366 'h2' => 'H2',
367 'h3' => 'H3',
368 'h4' => 'H4',
369 'h5' => 'H5',
370 'h6' => 'H6',
371 'div' => 'DIV',
372 'span' => 'SPAN',
373 'p' => 'P',
374 ],
375 'default' => 'h3',
376 ]
377 );
378
379 $this->end_controls_section();
380 }
381
382 /**
383 * Register cards repeater controls.
384 *
385 * @return void
386 */
387 protected function register_cards_controls(): void
388 {
389 $this->start_controls_section(
390 'kng_pdc_cards_section',
391 [
392 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Cards', 'king-addons'),
393 'tab' => Controls_Manager::TAB_CONTENT,
394 'condition' => [
395 'kng_pdc_mode' => 'cards',
396 ],
397 ]
398 );
399
400 $repeater = new Repeater();
401
402 $repeater->add_control(
403 'kng_pdc_media_type',
404 [
405 'label' => esc_html__('Media Type', 'king-addons'),
406 'type' => Controls_Manager::SELECT,
407 'options' => [
408 'none' => esc_html__('None', 'king-addons'),
409 'image' => esc_html__('Image', 'king-addons'),
410 'icon' => esc_html__('Icon', 'king-addons'),
411 ],
412 'default' => 'image',
413 ]
414 );
415
416 $repeater->add_control(
417 'kng_pdc_media_image',
418 [
419 'label' => esc_html__('Image', 'king-addons'),
420 'type' => Controls_Manager::MEDIA,
421 'default' => [
422 'url' => Utils::get_placeholder_image_src(),
423 ],
424 'condition' => [
425 'kng_pdc_media_type' => 'image',
426 ],
427 ]
428 );
429
430 $repeater->add_control(
431 'kng_pdc_media_icon',
432 [
433 'label' => esc_html__('Icon', 'king-addons'),
434 'type' => Controls_Manager::ICONS,
435 'default' => [
436 'value' => 'fas fa-layer-group',
437 'library' => 'solid',
438 ],
439 'condition' => [
440 'kng_pdc_media_type' => 'icon',
441 ],
442 ]
443 );
444
445 $repeater->add_responsive_control(
446 'kng_pdc_media_width',
447 [
448 'label' => esc_html__('Media Width', 'king-addons'),
449 'type' => Controls_Manager::SLIDER,
450 'size_units' => ['px', 'em', 'rem'],
451 'range' => [
452 'px' => ['min' => 40, 'max' => 320],
453 'em' => ['min' => 2, 'max' => 20],
454 'rem' => ['min' => 2, 'max' => 20],
455 ],
456 'default' => [
457 'size' => 120,
458 'unit' => 'px',
459 ],
460 'condition' => [
461 'kng_pdc_media_type!' => 'none',
462 ],
463 ]
464 );
465
466 $repeater->add_responsive_control(
467 'kng_pdc_icon_size',
468 [
469 'label' => esc_html__('Icon Size', 'king-addons'),
470 'type' => Controls_Manager::SLIDER,
471 'size_units' => ['px', 'em', 'rem'],
472 'range' => [
473 'px' => ['min' => 16, 'max' => 120],
474 'em' => ['min' => 1, 'max' => 8],
475 'rem' => ['min' => 1, 'max' => 8],
476 ],
477 'default' => [
478 'size' => 36,
479 'unit' => 'px',
480 ],
481 'condition' => [
482 'kng_pdc_media_type' => 'icon',
483 ],
484 ]
485 );
486
487 $repeater->add_control(
488 'kng_pdc_media_position',
489 [
490 'label' => esc_html__('Media Alignment', 'king-addons'),
491 'type' => Controls_Manager::SELECT,
492 'options' => [
493 'left' => esc_html__('Left', 'king-addons'),
494 'center' => esc_html__('Center', 'king-addons'),
495 'right' => esc_html__('Right', 'king-addons'),
496 ],
497 'default' => 'left',
498 'condition' => [
499 'kng_pdc_media_type!' => 'none',
500 ],
501 ]
502 );
503
504 $repeater->add_control(
505 'kng_pdc_title',
506 [
507 'label' => esc_html__('Title', 'king-addons'),
508 'type' => Controls_Manager::TEXT,
509 'default' => esc_html__('Depth Focused', 'king-addons'),
510 'label_block' => true,
511 ]
512 );
513
514 $repeater->add_control(
515 'kng_pdc_description',
516 [
517 'label' => esc_html__('Description', 'king-addons'),
518 'type' => Controls_Manager::TEXTAREA,
519 'default' => esc_html__('Layered motion elevates this card with subtle depth.', 'king-addons'),
520 'rows' => 4,
521 ]
522 );
523
524 $repeater->add_control(
525 'kng_pdc_button_text',
526 [
527 'label' => esc_html__('Button Text', 'king-addons'),
528 'type' => Controls_Manager::TEXT,
529 'default' => esc_html__('Learn more', 'king-addons'),
530 'label_block' => true,
531 ]
532 );
533
534 $repeater->add_control(
535 'kng_pdc_button_link',
536 [
537 'label' => esc_html__('Button Link', 'king-addons'),
538 'type' => Controls_Manager::URL,
539 'placeholder' => 'https://',
540 'show_external' => true,
541 'default' => [
542 'url' => '',
543 'is_external' => true,
544 ],
545 'label_block' => true,
546 ]
547 );
548
549 $repeater->add_control(
550 'kng_pdc_badge_text',
551 [
552 'label' => esc_html__('Badge Text', 'king-addons'),
553 'type' => Controls_Manager::TEXT,
554 'default' => esc_html__('Featured', 'king-addons'),
555 'label_block' => true,
556 ]
557 );
558
559 $repeater->add_control(
560 'kng_pdc_badge_position',
561 [
562 'label' => esc_html__('Badge Position', 'king-addons'),
563 'type' => Controls_Manager::SELECT,
564 'options' => [
565 'left' => esc_html__('Top Left', 'king-addons'),
566 'right' => esc_html__('Top Right', 'king-addons'),
567 ],
568 'default' => 'left',
569 ]
570 );
571
572 $this->add_control(
573 'kng_pdc_cards',
574 [
575 'label' => esc_html__('Cards', 'king-addons'),
576 'type' => Controls_Manager::REPEATER,
577 'fields' => $repeater->get_controls(),
578 'default' => [
579 [
580 'kng_pdc_title' => esc_html__('Premium Motion', 'king-addons'),
581 'kng_pdc_description' => esc_html__('Responsive depth and tilt for high-impact highlights.', 'king-addons'),
582 'kng_pdc_badge_text' => esc_html__('New', 'king-addons'),
583 ],
584 [
585 'kng_pdc_title' => esc_html__('Layered Clarity', 'king-addons'),
586 'kng_pdc_description' => esc_html__('Give key features visual separation with depth.', 'king-addons'),
587 'kng_pdc_badge_text' => esc_html__('Focus', 'king-addons'),
588 ],
589 [
590 'kng_pdc_title' => esc_html__('Smooth Response', 'king-addons'),
591 'kng_pdc_description' => esc_html__('Balanced motion keeps everything calm and premium.', 'king-addons'),
592 'kng_pdc_badge_text' => esc_html__('Pro', 'king-addons'),
593 ],
594 ],
595 'title_field' => '{{ kng_pdc_title }}',
596 ]
597 );
598
599 $this->end_controls_section();
600 }
601
602 /**
603 * Register single card controls.
604 *
605 * @return void
606 */
607 protected function register_single_card_controls(): void
608 {
609 $this->start_controls_section(
610 'kng_pdc_single_section',
611 [
612 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Single Card', 'king-addons'),
613 'tab' => Controls_Manager::TAB_CONTENT,
614 'condition' => [
615 'kng_pdc_mode' => 'single',
616 ],
617 ]
618 );
619
620 $this->add_control(
621 'kng_pdc_single_media_type',
622 [
623 'label' => esc_html__('Media Type', 'king-addons'),
624 'type' => Controls_Manager::SELECT,
625 'options' => [
626 'none' => esc_html__('None', 'king-addons'),
627 'image' => esc_html__('Image', 'king-addons'),
628 'icon' => esc_html__('Icon', 'king-addons'),
629 ],
630 'default' => 'image',
631 ]
632 );
633
634 $this->add_control(
635 'kng_pdc_single_media_image',
636 [
637 'label' => esc_html__('Image', 'king-addons'),
638 'type' => Controls_Manager::MEDIA,
639 'default' => [
640 'url' => Utils::get_placeholder_image_src(),
641 ],
642 'condition' => [
643 'kng_pdc_single_media_type' => 'image',
644 ],
645 ]
646 );
647
648 $this->add_control(
649 'kng_pdc_single_media_icon',
650 [
651 'label' => esc_html__('Icon', 'king-addons'),
652 'type' => Controls_Manager::ICONS,
653 'default' => [
654 'value' => 'fas fa-layer-group',
655 'library' => 'solid',
656 ],
657 'condition' => [
658 'kng_pdc_single_media_type' => 'icon',
659 ],
660 ]
661 );
662
663 $this->add_responsive_control(
664 'kng_pdc_single_media_width',
665 [
666 'label' => esc_html__('Media Width', 'king-addons'),
667 'type' => Controls_Manager::SLIDER,
668 'size_units' => ['px', 'em', 'rem'],
669 'range' => [
670 'px' => ['min' => 40, 'max' => 320],
671 'em' => ['min' => 2, 'max' => 20],
672 'rem' => ['min' => 2, 'max' => 20],
673 ],
674 'default' => [
675 'size' => 120,
676 'unit' => 'px',
677 ],
678 'condition' => [
679 'kng_pdc_single_media_type!' => 'none',
680 ],
681 ]
682 );
683
684 $this->add_responsive_control(
685 'kng_pdc_single_icon_size',
686 [
687 'label' => esc_html__('Icon Size', 'king-addons'),
688 'type' => Controls_Manager::SLIDER,
689 'size_units' => ['px', 'em', 'rem'],
690 'range' => [
691 'px' => ['min' => 16, 'max' => 120],
692 'em' => ['min' => 1, 'max' => 8],
693 'rem' => ['min' => 1, 'max' => 8],
694 ],
695 'default' => [
696 'size' => 36,
697 'unit' => 'px',
698 ],
699 'condition' => [
700 'kng_pdc_single_media_type' => 'icon',
701 ],
702 ]
703 );
704
705 $this->add_control(
706 'kng_pdc_single_media_position',
707 [
708 'label' => esc_html__('Media Alignment', 'king-addons'),
709 'type' => Controls_Manager::SELECT,
710 'options' => [
711 'left' => esc_html__('Left', 'king-addons'),
712 'center' => esc_html__('Center', 'king-addons'),
713 'right' => esc_html__('Right', 'king-addons'),
714 ],
715 'default' => 'left',
716 'condition' => [
717 'kng_pdc_single_media_type!' => 'none',
718 ],
719 ]
720 );
721
722 $this->add_control(
723 'kng_pdc_single_title',
724 [
725 'label' => esc_html__('Title', 'king-addons'),
726 'type' => Controls_Manager::TEXT,
727 'default' => esc_html__('Depth Focused', 'king-addons'),
728 'label_block' => true,
729 ]
730 );
731
732 $this->add_control(
733 'kng_pdc_single_description',
734 [
735 'label' => esc_html__('Description', 'king-addons'),
736 'type' => Controls_Manager::TEXTAREA,
737 'default' => esc_html__('Layered motion elevates this card with subtle depth.', 'king-addons'),
738 'rows' => 4,
739 ]
740 );
741
742 $this->add_control(
743 'kng_pdc_single_button_text',
744 [
745 'label' => esc_html__('Button Text', 'king-addons'),
746 'type' => Controls_Manager::TEXT,
747 'default' => esc_html__('Learn more', 'king-addons'),
748 'label_block' => true,
749 ]
750 );
751
752 $this->add_control(
753 'kng_pdc_single_button_link',
754 [
755 'label' => esc_html__('Button Link', 'king-addons'),
756 'type' => Controls_Manager::URL,
757 'placeholder' => 'https://',
758 'show_external' => true,
759 'default' => [
760 'url' => '',
761 'is_external' => true,
762 ],
763 'label_block' => true,
764 ]
765 );
766
767 $this->add_control(
768 'kng_pdc_single_badge_text',
769 [
770 'label' => esc_html__('Badge Text', 'king-addons'),
771 'type' => Controls_Manager::TEXT,
772 'default' => esc_html__('Featured', 'king-addons'),
773 'label_block' => true,
774 ]
775 );
776
777 $this->add_control(
778 'kng_pdc_single_badge_position',
779 [
780 'label' => esc_html__('Badge Position', 'king-addons'),
781 'type' => Controls_Manager::SELECT,
782 'options' => [
783 'left' => esc_html__('Top Left', 'king-addons'),
784 'right' => esc_html__('Top Right', 'king-addons'),
785 ],
786 'default' => 'left',
787 ]
788 );
789
790 $this->end_controls_section();
791 }
792
793 /**
794 * Register interaction controls.
795 *
796 * @return void
797 */
798 protected function register_interaction_controls(): void
799 {
800 $this->start_controls_section(
801 'kng_pdc_interaction_section',
802 [
803 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Interaction', 'king-addons'),
804 'tab' => Controls_Manager::TAB_CONTENT,
805 ]
806 );
807
808 $this->add_control(
809 'kng_pdc_enable_tilt',
810 [
811 'label' => esc_html__('Enable Tilt', 'king-addons'),
812 'type' => Controls_Manager::SWITCHER,
813 'return_value' => 'yes',
814 'default' => 'yes',
815 ]
816 );
817
818 $this->add_control(
819 'kng_pdc_enable_parallax',
820 [
821 'label' => esc_html__('Enable Parallax', 'king-addons'),
822 'type' => Controls_Manager::SWITCHER,
823 'return_value' => 'yes',
824 'default' => 'yes',
825 ]
826 );
827
828 $this->add_control(
829 'kng_pdc_trigger',
830 [
831 'label' => esc_html__('Trigger', 'king-addons'),
832 'type' => Controls_Manager::SELECT,
833 'options' => [
834 'hover' => esc_html__('On Hover', 'king-addons'),
835 'always' => esc_html__('Always Active', 'king-addons'),
836 ],
837 'default' => 'hover',
838 ]
839 );
840
841 $this->add_control(
842 'kng_pdc_intensity',
843 [
844 'label' => esc_html__('Intensity', 'king-addons'),
845 'type' => Controls_Manager::SLIDER,
846 'size_units' => [],
847 'range' => [
848 '' => ['min' => 0, 'max' => 100],
849 ],
850 'default' => [
851 'size' => 60,
852 ],
853 ]
854 );
855
856 $this->add_control(
857 'kng_pdc_perspective',
858 [
859 'label' => esc_html__('Perspective (px)', 'king-addons'),
860 'type' => Controls_Manager::SLIDER,
861 'size_units' => ['px'],
862 'range' => [
863 'px' => ['min' => 200, 'max' => 2000],
864 ],
865 'default' => [
866 'size' => 900,
867 'unit' => 'px',
868 ],
869 'selectors' => [
870 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-perspective: {{SIZE}}{{UNIT}};',
871 ],
872 ]
873 );
874
875 $this->add_control(
876 'kng_pdc_max_tilt',
877 [
878 'label' => esc_html__('Max Tilt (deg)', 'king-addons'),
879 'type' => Controls_Manager::SLIDER,
880 'size_units' => [],
881 'range' => [
882 '' => ['min' => 0, 'max' => 30],
883 ],
884 'default' => [
885 'size' => 12,
886 ],
887 ]
888 );
889
890 $this->add_control(
891 'kng_pdc_depth_strength',
892 [
893 'label' => esc_html__('Parallax Depth (px)', 'king-addons'),
894 'type' => Controls_Manager::SLIDER,
895 'size_units' => [],
896 'range' => [
897 '' => ['min' => 0, 'max' => 60],
898 ],
899 'default' => [
900 'size' => 18,
901 ],
902 ]
903 );
904
905 $this->add_control(
906 'kng_pdc_depth_bg',
907 [
908 'label' => esc_html__('Background Layer Depth', 'king-addons'),
909 'type' => Controls_Manager::SLIDER,
910 'size_units' => [],
911 'range' => [
912 '' => ['min' => -1, 'max' => 1, 'step' => 0.05],
913 ],
914 'default' => [
915 'size' => 0.2,
916 ],
917 ]
918 );
919
920 $this->add_control(
921 'kng_pdc_depth_media',
922 [
923 'label' => esc_html__('Media Layer Depth', 'king-addons'),
924 'type' => Controls_Manager::SLIDER,
925 'size_units' => [],
926 'range' => [
927 '' => ['min' => -1, 'max' => 1, 'step' => 0.05],
928 ],
929 'default' => [
930 'size' => 0.35,
931 ],
932 ]
933 );
934
935 $this->add_control(
936 'kng_pdc_depth_content',
937 [
938 'label' => esc_html__('Content Layer Depth', 'king-addons'),
939 'type' => Controls_Manager::SLIDER,
940 'size_units' => [],
941 'range' => [
942 '' => ['min' => -1, 'max' => 1, 'step' => 0.05],
943 ],
944 'default' => [
945 'size' => 0.5,
946 ],
947 ]
948 );
949
950 $this->add_control(
951 'kng_pdc_smoothing',
952 [
953 'label' => esc_html__('Smoothing', 'king-addons'),
954 'type' => Controls_Manager::SLIDER,
955 'size_units' => [],
956 'range' => [
957 '' => ['min' => 0.02, 'max' => 0.4, 'step' => 0.01],
958 ],
959 'default' => [
960 'size' => 0.12,
961 ],
962 ]
963 );
964
965 $this->add_control(
966 'kng_pdc_reset_duration',
967 [
968 'label' => esc_html__('Hover Out Duration (ms)', 'king-addons'),
969 'type' => Controls_Manager::SLIDER,
970 'size_units' => [],
971 'range' => [
972 '' => ['min' => 100, 'max' => 1200, 'step' => 50],
973 ],
974 'default' => [
975 'size' => 350,
976 ],
977 ]
978 );
979
980 $this->add_control(
981 'kng_pdc_reduce_motion',
982 [
983 'label' => esc_html__('Respect Reduced Motion', 'king-addons'),
984 'type' => Controls_Manager::SWITCHER,
985 'return_value' => 'yes',
986 'default' => 'yes',
987 ]
988 );
989
990 $this->add_control(
991 'kng_pdc_disable_touch',
992 [
993 'label' => esc_html__('Disable on Touch Devices', 'king-addons'),
994 'type' => Controls_Manager::SWITCHER,
995 'return_value' => 'yes',
996 'default' => 'yes',
997 ]
998 );
999
1000 $this->end_controls_section();
1001 }
1002
1003 /**
1004 * Register style controls.
1005 *
1006 * @return void
1007 */
1008 protected function register_style_controls(): void
1009 {
1010 $this->register_style_card_controls();
1011 $this->register_style_typography_controls();
1012 $this->register_style_badge_controls();
1013 $this->register_style_button_controls();
1014 $this->register_style_media_controls();
1015 $this->register_style_layer_controls();
1016 }
1017
1018 /**
1019 * Card base style controls.
1020 *
1021 * @return void
1022 */
1023 protected function register_style_card_controls(): void
1024 {
1025 $this->start_controls_section(
1026 'kng_pdc_style_card',
1027 [
1028 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Card', 'king-addons'),
1029 'tab' => Controls_Manager::TAB_STYLE,
1030 ]
1031 );
1032
1033 $this->add_group_control(
1034 Group_Control_Background::get_type(),
1035 [
1036 'name' => 'kng_pdc_card_background',
1037 'selector' => '{{WRAPPER}} .king-addons-parallax-depth-cards__card',
1038 ]
1039 );
1040
1041 $this->add_group_control(
1042 Group_Control_Border::get_type(),
1043 [
1044 'name' => 'kng_pdc_card_border',
1045 'selector' => '{{WRAPPER}} .king-addons-parallax-depth-cards__card',
1046 ]
1047 );
1048
1049 $this->add_responsive_control(
1050 'kng_pdc_card_radius',
1051 [
1052 'label' => esc_html__('Border Radius', 'king-addons'),
1053 'type' => Controls_Manager::SLIDER,
1054 'size_units' => ['px', '%'],
1055 'selectors' => [
1056 '{{WRAPPER}} .king-addons-parallax-depth-cards__card' => 'border-radius: {{SIZE}}{{UNIT}};',
1057 ],
1058 ]
1059 );
1060
1061 $this->add_group_control(
1062 Group_Control_Box_Shadow::get_type(),
1063 [
1064 'name' => 'kng_pdc_card_shadow',
1065 'selector' => '{{WRAPPER}} .king-addons-parallax-depth-cards__card',
1066 ]
1067 );
1068
1069 $this->add_group_control(
1070 Group_Control_Box_Shadow::get_type(),
1071 [
1072 'name' => 'kng_pdc_card_shadow_hover',
1073 'selector' => '{{WRAPPER}} .king-addons-parallax-depth-cards__card:hover, {{WRAPPER}} .king-addons-parallax-depth-cards__card:focus-within',
1074 ]
1075 );
1076
1077 $this->add_control(
1078 'kng_pdc_card_hover_bg',
1079 [
1080 'label' => esc_html__('Hover Background', 'king-addons'),
1081 'type' => Controls_Manager::COLOR,
1082 'selectors' => [
1083 '{{WRAPPER}} .king-addons-parallax-depth-cards__card:hover' => 'background-color: {{VALUE}};',
1084 '{{WRAPPER}} .king-addons-parallax-depth-cards__card:focus-within' => 'background-color: {{VALUE}};',
1085 ],
1086 ]
1087 );
1088
1089 $this->add_control(
1090 'kng_pdc_card_hover_border',
1091 [
1092 'label' => esc_html__('Hover Border Color', 'king-addons'),
1093 'type' => Controls_Manager::COLOR,
1094 'selectors' => [
1095 '{{WRAPPER}} .king-addons-parallax-depth-cards__card:hover' => 'border-color: {{VALUE}};',
1096 '{{WRAPPER}} .king-addons-parallax-depth-cards__card:focus-within' => 'border-color: {{VALUE}};',
1097 ],
1098 ]
1099 );
1100
1101 $this->add_responsive_control(
1102 'kng_pdc_card_padding',
1103 [
1104 'label' => esc_html__('Padding', 'king-addons'),
1105 'type' => Controls_Manager::DIMENSIONS,
1106 'size_units' => ['px', 'em', 'rem'],
1107 'selectors' => [
1108 '{{WRAPPER}} .king-addons-parallax-depth-cards__card-inner' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1109 ],
1110 ]
1111 );
1112
1113 $this->add_control(
1114 'kng_pdc_hover_transform_heading',
1115 [
1116 'label' => esc_html__('Hover Transform', 'king-addons'),
1117 'type' => Controls_Manager::HEADING,
1118 'separator' => 'before',
1119 ]
1120 );
1121
1122 $this->add_control(
1123 'kng_pdc_hover_scale',
1124 [
1125 'label' => esc_html__('Hover Scale', 'king-addons'),
1126 'type' => Controls_Manager::SLIDER,
1127 'range' => [
1128 'px' => ['min' => 0.9, 'max' => 1.2, 'step' => 0.01],
1129 ],
1130 'default' => [
1131 'size' => 1,
1132 ],
1133 'selectors' => [
1134 '{{WRAPPER}} .king-addons-parallax-depth-cards__card:hover' => '--ka-pdc-hover-scale: {{SIZE}};',
1135 '{{WRAPPER}} .king-addons-parallax-depth-cards__card:focus-within' => '--ka-pdc-hover-scale: {{SIZE}};',
1136 ],
1137 ]
1138 );
1139
1140 $this->add_control(
1141 'kng_pdc_hover_lift',
1142 [
1143 'label' => esc_html__('Hover Lift (Y)', 'king-addons'),
1144 'type' => Controls_Manager::SLIDER,
1145 'size_units' => ['px'],
1146 'range' => [
1147 'px' => ['min' => -20, 'max' => 0],
1148 ],
1149 'default' => [
1150 'size' => 0,
1151 'unit' => 'px',
1152 ],
1153 'selectors' => [
1154 '{{WRAPPER}} .king-addons-parallax-depth-cards__card:hover' => '--ka-pdc-hover-lift: {{SIZE}}{{UNIT}};',
1155 '{{WRAPPER}} .king-addons-parallax-depth-cards__card:focus-within' => '--ka-pdc-hover-lift: {{SIZE}}{{UNIT}};',
1156 ],
1157 ]
1158 );
1159
1160 $this->end_controls_section();
1161 }
1162
1163 /**
1164 * Typography style controls.
1165 *
1166 * @return void
1167 */
1168 protected function register_style_typography_controls(): void
1169 {
1170 $this->start_controls_section(
1171 'kng_pdc_style_typography',
1172 [
1173 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Typography', 'king-addons'),
1174 'tab' => Controls_Manager::TAB_STYLE,
1175 ]
1176 );
1177
1178 $this->add_group_control(
1179 Group_Control_Typography::get_type(),
1180 [
1181 'name' => 'kng_pdc_title_typography',
1182 'selector' => '{{WRAPPER}} .king-addons-parallax-depth-cards__title',
1183 ]
1184 );
1185
1186 $this->add_control(
1187 'kng_pdc_title_color',
1188 [
1189 'label' => esc_html__('Title Color', 'king-addons'),
1190 'type' => Controls_Manager::COLOR,
1191 'selectors' => [
1192 '{{WRAPPER}} .king-addons-parallax-depth-cards__title' => 'color: {{VALUE}};',
1193 ],
1194 ]
1195 );
1196
1197 $this->add_group_control(
1198 Group_Control_Typography::get_type(),
1199 [
1200 'name' => 'kng_pdc_description_typography',
1201 'selector' => '{{WRAPPER}} .king-addons-parallax-depth-cards__description',
1202 ]
1203 );
1204
1205 $this->add_control(
1206 'kng_pdc_description_color',
1207 [
1208 'label' => esc_html__('Description Color', 'king-addons'),
1209 'type' => Controls_Manager::COLOR,
1210 'selectors' => [
1211 '{{WRAPPER}} .king-addons-parallax-depth-cards__description' => 'color: {{VALUE}};',
1212 ],
1213 ]
1214 );
1215
1216 $this->add_responsive_control(
1217 'kng_pdc_content_gap',
1218 [
1219 'label' => esc_html__('Content Spacing', 'king-addons'),
1220 'type' => Controls_Manager::SLIDER,
1221 'size_units' => ['px', 'em', 'rem'],
1222 'range' => [
1223 'px' => ['min' => 0, 'max' => 40],
1224 'em' => ['min' => 0, 'max' => 3],
1225 'rem' => ['min' => 0, 'max' => 3],
1226 ],
1227 'selectors' => [
1228 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-content-gap: {{SIZE}}{{UNIT}};',
1229 ],
1230 ]
1231 );
1232
1233 $this->add_responsive_control(
1234 'kng_pdc_media_spacing',
1235 [
1236 'label' => esc_html__('Media Bottom Spacing', 'king-addons'),
1237 'type' => Controls_Manager::SLIDER,
1238 'size_units' => ['px', 'em', 'rem'],
1239 'range' => [
1240 'px' => ['min' => 0, 'max' => 60],
1241 'em' => ['min' => 0, 'max' => 4],
1242 'rem' => ['min' => 0, 'max' => 4],
1243 ],
1244 'selectors' => [
1245 '{{WRAPPER}} .king-addons-parallax-depth-cards__layer--media' => 'margin-bottom: {{SIZE}}{{UNIT}};',
1246 ],
1247 ]
1248 );
1249
1250 $this->end_controls_section();
1251 }
1252
1253 /**
1254 * Badge style controls.
1255 *
1256 * @return void
1257 */
1258 protected function register_style_badge_controls(): void
1259 {
1260 $this->start_controls_section(
1261 'kng_pdc_style_badge',
1262 [
1263 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Badge', 'king-addons'),
1264 'tab' => Controls_Manager::TAB_STYLE,
1265 ]
1266 );
1267
1268 $this->add_group_control(
1269 Group_Control_Typography::get_type(),
1270 [
1271 'name' => 'kng_pdc_badge_typography',
1272 'selector' => '{{WRAPPER}} .king-addons-parallax-depth-cards__badge',
1273 ]
1274 );
1275
1276 $this->add_control(
1277 'kng_pdc_badge_text_color',
1278 [
1279 'label' => esc_html__('Text Color', 'king-addons'),
1280 'type' => Controls_Manager::COLOR,
1281 'selectors' => [
1282 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-badge-color: {{VALUE}};',
1283 ],
1284 ]
1285 );
1286
1287 $this->add_control(
1288 'kng_pdc_badge_bg',
1289 [
1290 'label' => esc_html__('Background', 'king-addons'),
1291 'type' => Controls_Manager::COLOR,
1292 'selectors' => [
1293 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-badge-bg: {{VALUE}};',
1294 ],
1295 ]
1296 );
1297
1298 $this->add_responsive_control(
1299 'kng_pdc_badge_radius',
1300 [
1301 'label' => esc_html__('Border Radius', 'king-addons'),
1302 'type' => Controls_Manager::SLIDER,
1303 'size_units' => ['px', '%'],
1304 'selectors' => [
1305 '{{WRAPPER}} .king-addons-parallax-depth-cards__badge' => 'border-radius: {{SIZE}}{{UNIT}};',
1306 ],
1307 ]
1308 );
1309
1310 $this->add_responsive_control(
1311 'kng_pdc_badge_padding',
1312 [
1313 'label' => esc_html__('Padding', 'king-addons'),
1314 'type' => Controls_Manager::DIMENSIONS,
1315 'size_units' => ['px', 'em', 'rem'],
1316 'selectors' => [
1317 '{{WRAPPER}} .king-addons-parallax-depth-cards__badge' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1318 ],
1319 ]
1320 );
1321
1322 $this->end_controls_section();
1323 }
1324
1325 /**
1326 * Button style controls.
1327 *
1328 * @return void
1329 */
1330 protected function register_style_button_controls(): void
1331 {
1332 $this->start_controls_section(
1333 'kng_pdc_style_button',
1334 [
1335 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Button', 'king-addons'),
1336 'tab' => Controls_Manager::TAB_STYLE,
1337 ]
1338 );
1339
1340 $this->add_group_control(
1341 Group_Control_Typography::get_type(),
1342 [
1343 'name' => 'kng_pdc_button_typography',
1344 'selector' => '{{WRAPPER}} .king-addons-parallax-depth-cards__button',
1345 ]
1346 );
1347
1348 $this->start_controls_tabs('kng_pdc_button_tabs');
1349
1350 $this->start_controls_tab(
1351 'kng_pdc_button_tab_normal',
1352 [
1353 'label' => esc_html__('Normal', 'king-addons'),
1354 ]
1355 );
1356
1357 $this->add_control(
1358 'kng_pdc_button_text_color',
1359 [
1360 'label' => esc_html__('Text Color', 'king-addons'),
1361 'type' => Controls_Manager::COLOR,
1362 'selectors' => [
1363 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-button-color: {{VALUE}};',
1364 ],
1365 ]
1366 );
1367
1368 $this->add_control(
1369 'kng_pdc_button_bg',
1370 [
1371 'label' => esc_html__('Background', 'king-addons'),
1372 'type' => Controls_Manager::COLOR,
1373 'selectors' => [
1374 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-button-bg: {{VALUE}};',
1375 ],
1376 ]
1377 );
1378
1379 $this->add_control(
1380 'kng_pdc_button_border',
1381 [
1382 'label' => esc_html__('Border Color', 'king-addons'),
1383 'type' => Controls_Manager::COLOR,
1384 'selectors' => [
1385 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-button-border: {{VALUE}};',
1386 ],
1387 ]
1388 );
1389
1390 $this->end_controls_tab();
1391
1392 $this->start_controls_tab(
1393 'kng_pdc_button_tab_hover',
1394 [
1395 'label' => esc_html__('Hover', 'king-addons'),
1396 ]
1397 );
1398
1399 $this->add_control(
1400 'kng_pdc_button_text_color_hover',
1401 [
1402 'label' => esc_html__('Text Color', 'king-addons'),
1403 'type' => Controls_Manager::COLOR,
1404 'selectors' => [
1405 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-button-color-hover: {{VALUE}};',
1406 ],
1407 ]
1408 );
1409
1410 $this->add_control(
1411 'kng_pdc_button_bg_hover',
1412 [
1413 'label' => esc_html__('Background', 'king-addons'),
1414 'type' => Controls_Manager::COLOR,
1415 'selectors' => [
1416 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-button-bg-hover: {{VALUE}};',
1417 ],
1418 ]
1419 );
1420
1421 $this->add_control(
1422 'kng_pdc_button_border_hover',
1423 [
1424 'label' => esc_html__('Border Color', 'king-addons'),
1425 'type' => Controls_Manager::COLOR,
1426 'selectors' => [
1427 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-button-border-hover: {{VALUE}};',
1428 ],
1429 ]
1430 );
1431
1432 $this->end_controls_tab();
1433 $this->end_controls_tabs();
1434
1435 $this->add_responsive_control(
1436 'kng_pdc_button_radius',
1437 [
1438 'label' => esc_html__('Border Radius', 'king-addons'),
1439 'type' => Controls_Manager::SLIDER,
1440 'size_units' => ['px', '%'],
1441 'selectors' => [
1442 '{{WRAPPER}} .king-addons-parallax-depth-cards__button' => 'border-radius: {{SIZE}}{{UNIT}};',
1443 ],
1444 ]
1445 );
1446
1447 $this->add_responsive_control(
1448 'kng_pdc_button_border_width',
1449 [
1450 'label' => esc_html__('Border Width', 'king-addons'),
1451 'type' => Controls_Manager::SLIDER,
1452 'size_units' => ['px'],
1453 'range' => [
1454 'px' => ['min' => 0, 'max' => 5],
1455 ],
1456 'selectors' => [
1457 '{{WRAPPER}} .king-addons-parallax-depth-cards__button' => 'border-width: {{SIZE}}{{UNIT}};',
1458 ],
1459 ]
1460 );
1461
1462 $this->add_responsive_control(
1463 'kng_pdc_button_padding',
1464 [
1465 'label' => esc_html__('Padding', 'king-addons'),
1466 'type' => Controls_Manager::DIMENSIONS,
1467 'size_units' => ['px', 'em', 'rem'],
1468 'selectors' => [
1469 '{{WRAPPER}} .king-addons-parallax-depth-cards__button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1470 ],
1471 ]
1472 );
1473
1474 $this->end_controls_section();
1475 }
1476
1477 /**
1478 * Media style controls.
1479 *
1480 * @return void
1481 */
1482 protected function register_style_media_controls(): void
1483 {
1484 $this->start_controls_section(
1485 'kng_pdc_style_media',
1486 [
1487 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Media', 'king-addons'),
1488 'tab' => Controls_Manager::TAB_STYLE,
1489 ]
1490 );
1491
1492 $this->add_group_control(
1493 Group_Control_Image_Size::get_type(),
1494 [
1495 'name' => 'kng_pdc_media_image_size',
1496 'default' => 'medium',
1497 ]
1498 );
1499
1500 $this->add_control(
1501 'kng_pdc_icon_color',
1502 [
1503 'label' => esc_html__('Icon Color', 'king-addons'),
1504 'type' => Controls_Manager::COLOR,
1505 'selectors' => [
1506 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-icon-color: {{VALUE}};',
1507 ],
1508 ]
1509 );
1510
1511 $this->add_control(
1512 'kng_pdc_icon_bg',
1513 [
1514 'label' => esc_html__('Icon Background', 'king-addons'),
1515 'type' => Controls_Manager::COLOR,
1516 'selectors' => [
1517 '{{WRAPPER}} .king-addons-parallax-depth-cards__icon' => 'background-color: {{VALUE}};',
1518 ],
1519 ]
1520 );
1521
1522 $this->add_responsive_control(
1523 'kng_pdc_icon_padding',
1524 [
1525 'label' => esc_html__('Icon Padding', 'king-addons'),
1526 'type' => Controls_Manager::SLIDER,
1527 'size_units' => ['px', 'em'],
1528 'range' => [
1529 'px' => ['min' => 0, 'max' => 40],
1530 'em' => ['min' => 0, 'max' => 3],
1531 ],
1532 'selectors' => [
1533 '{{WRAPPER}} .king-addons-parallax-depth-cards__icon' => 'padding: {{SIZE}}{{UNIT}};',
1534 ],
1535 ]
1536 );
1537
1538 $this->add_responsive_control(
1539 'kng_pdc_icon_border_radius',
1540 [
1541 'label' => esc_html__('Icon Border Radius', 'king-addons'),
1542 'type' => Controls_Manager::SLIDER,
1543 'size_units' => ['px', '%'],
1544 'selectors' => [
1545 '{{WRAPPER}} .king-addons-parallax-depth-cards__icon' => 'border-radius: {{SIZE}}{{UNIT}};',
1546 ],
1547 ]
1548 );
1549
1550 $this->add_responsive_control(
1551 'kng_pdc_media_radius',
1552 [
1553 'label' => esc_html__('Image Radius', 'king-addons'),
1554 'type' => Controls_Manager::SLIDER,
1555 'size_units' => ['px', '%'],
1556 'selectors' => [
1557 '{{WRAPPER}} .king-addons-parallax-depth-cards' => '--ka-pdc-media-radius: {{SIZE}}{{UNIT}};',
1558 ],
1559 ]
1560 );
1561
1562 $this->end_controls_section();
1563 }
1564
1565 /**
1566 * Background layer style controls.
1567 *
1568 * @return void
1569 */
1570 protected function register_style_layer_controls(): void
1571 {
1572 $this->start_controls_section(
1573 'kng_pdc_style_layer',
1574 [
1575 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Background Layer', 'king-addons'),
1576 'tab' => Controls_Manager::TAB_STYLE,
1577 ]
1578 );
1579
1580 $this->add_group_control(
1581 Group_Control_Background::get_type(),
1582 [
1583 'name' => 'kng_pdc_layer_background',
1584 'selector' => '{{WRAPPER}} .king-addons-parallax-depth-cards__layer--bg',
1585 ]
1586 );
1587
1588 $this->end_controls_section();
1589 }
1590
1591 /**
1592 * Render a card.
1593 *
1594 * @param array<string, mixed> $settings Widget settings.
1595 * @param array<string, mixed> $card Card data.
1596 * @param array<string, float> $depths Depth settings.
1597 *
1598 * @return void
1599 */
1600 protected function render_card(array $settings, array $card, array $depths): void
1601 {
1602 $title = trim((string) ($card['kng_pdc_title'] ?? ''));
1603 $description = trim((string) ($card['kng_pdc_description'] ?? ''));
1604 $badge_text = trim((string) ($card['kng_pdc_badge_text'] ?? ''));
1605 $badge_position = $card['kng_pdc_badge_position'] ?? 'left';
1606 $title_tag = $this->sanitize_html_tag($settings['kng_pdc_title_tag'] ?? 'h3');
1607
1608 $button_text = trim((string) ($card['kng_pdc_button_text'] ?? ''));
1609 $button_link = is_array($card['kng_pdc_button_link'] ?? null) ? $card['kng_pdc_button_link'] : [];
1610 $button_url = $button_link['url'] ?? '';
1611
1612 $media_type = $card['kng_pdc_media_type'] ?? 'none';
1613 $media_position = $card['kng_pdc_media_position'] ?? 'left';
1614
1615 $media_width_value = $this->get_slider_css_value($card['kng_pdc_media_width'] ?? null, 'px');
1616 $icon_size_value = $this->get_slider_css_value($card['kng_pdc_icon_size'] ?? null, 'px');
1617
1618 $media_styles = [];
1619 if ($media_width_value !== '') {
1620 $media_styles[] = '--ka-pdc-media-width: ' . $media_width_value . ';';
1621 }
1622 if ($icon_size_value !== '') {
1623 $media_styles[] = '--ka-pdc-icon-size: ' . $icon_size_value . ';';
1624 }
1625 $media_style_attr = !empty($media_styles) ? ' style="' . esc_attr(implode(' ', $media_styles)) . '"' : '';
1626
1627 $card_classes = ['king-addons-parallax-depth-cards__card'];
1628 if (!empty($card['_id'])) {
1629 $card_classes[] = 'elementor-repeater-item-' . $card['_id'];
1630 }
1631
1632 $badge_class = 'king-addons-parallax-depth-cards__badge is-' . sanitize_html_class($badge_position);
1633 $media_class = 'king-addons-parallax-depth-cards__media is-align-' . sanitize_html_class($media_position);
1634
1635 ?>
1636 <article class="<?php echo esc_attr(implode(' ', $card_classes)); ?>">
1637 <div class="king-addons-parallax-depth-cards__card-inner">
1638 <div class="king-addons-parallax-depth-cards__layer king-addons-parallax-depth-cards__layer--bg" data-depth="<?php echo esc_attr((string) $depths['bg']); ?>"></div>
1639
1640 <?php if ($media_type !== 'none') : ?>
1641 <div class="king-addons-parallax-depth-cards__layer king-addons-parallax-depth-cards__layer--media" data-depth="<?php echo esc_attr((string) $depths['media']); ?>">
1642 <div class="<?php echo esc_attr($media_class); ?>"<?php echo $media_style_attr; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1643 <?php if ($media_type === 'image' && !empty($card['kng_pdc_media_image']['url'])) : ?>
1644 <?php
1645 $image_settings = $card;
1646 if (isset($settings['kng_pdc_media_image_size_size'])) {
1647 $image_settings['kng_pdc_media_image_size_size'] = $settings['kng_pdc_media_image_size_size'];
1648 }
1649 if (isset($settings['kng_pdc_media_image_size_custom_dimension'])) {
1650 $image_settings['kng_pdc_media_image_size_custom_dimension'] = $settings['kng_pdc_media_image_size_custom_dimension'];
1651 }
1652 $image_html = Group_Control_Image_Size::get_attachment_image_html($image_settings, 'kng_pdc_media_image_size', 'kng_pdc_media_image');
1653 echo wp_kses_post($image_html);
1654 ?>
1655 <?php elseif ($media_type === 'icon' && !empty($card['kng_pdc_media_icon']['value'])) : ?>
1656 <span class="king-addons-parallax-depth-cards__icon" aria-hidden="true">
1657 <?php Icons_Manager::render_icon($card['kng_pdc_media_icon'], ['aria-hidden' => 'true']); ?>
1658 </span>
1659 <?php endif; ?>
1660 </div>
1661 </div>
1662 <?php endif; ?>
1663
1664 <div class="king-addons-parallax-depth-cards__layer king-addons-parallax-depth-cards__layer--content" data-depth="<?php echo esc_attr((string) $depths['content']); ?>">
1665 <div class="king-addons-parallax-depth-cards__content">
1666 <?php if ($badge_text !== '') : ?>
1667 <span class="<?php echo esc_attr($badge_class); ?>"><?php echo esc_html($badge_text); ?></span>
1668 <?php endif; ?>
1669
1670 <?php if ($title !== '') : ?>
1671 <<?php echo esc_html($title_tag); ?> class="king-addons-parallax-depth-cards__title"><?php echo esc_html($title); ?></<?php echo esc_html($title_tag); ?>>
1672 <?php endif; ?>
1673
1674 <?php if ($description !== '') : ?>
1675 <p class="king-addons-parallax-depth-cards__description"><?php echo esc_html($description); ?></p>
1676 <?php endif; ?>
1677
1678 <?php if ($button_text !== '') : ?>
1679 <?php if ($button_url !== '') : ?>
1680 <a class="king-addons-parallax-depth-cards__button"<?php echo $this->build_button_attributes($button_link); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
1681 <?php echo esc_html($button_text); ?>
1682 </a>
1683 <?php else : ?>
1684 <button class="king-addons-parallax-depth-cards__button" type="button">
1685 <?php echo esc_html($button_text); ?>
1686 </button>
1687 <?php endif; ?>
1688 <?php endif; ?>
1689 </div>
1690 </div>
1691 </div>
1692 </article>
1693 <?php
1694 }
1695
1696 /**
1697 * Map single card settings to card data.
1698 *
1699 * @param array<string, mixed> $settings Widget settings.
1700 *
1701 * @return array<string, mixed>
1702 */
1703 protected function get_single_card_data(array $settings): array
1704 {
1705 return [
1706 'kng_pdc_media_type' => $settings['kng_pdc_single_media_type'] ?? 'none',
1707 'kng_pdc_media_image' => $settings['kng_pdc_single_media_image'] ?? [],
1708 'kng_pdc_media_icon' => $settings['kng_pdc_single_media_icon'] ?? [],
1709 'kng_pdc_media_width' => $settings['kng_pdc_single_media_width'] ?? [],
1710 'kng_pdc_icon_size' => $settings['kng_pdc_single_icon_size'] ?? [],
1711 'kng_pdc_media_position' => $settings['kng_pdc_single_media_position'] ?? 'left',
1712 'kng_pdc_title' => $settings['kng_pdc_single_title'] ?? '',
1713 'kng_pdc_description' => $settings['kng_pdc_single_description'] ?? '',
1714 'kng_pdc_button_text' => $settings['kng_pdc_single_button_text'] ?? '',
1715 'kng_pdc_button_link' => $settings['kng_pdc_single_button_link'] ?? [],
1716 'kng_pdc_badge_text' => $settings['kng_pdc_single_badge_text'] ?? '',
1717 'kng_pdc_badge_position' => $settings['kng_pdc_single_badge_position'] ?? 'left',
1718 ];
1719 }
1720
1721 /**
1722 * Build button attributes.
1723 *
1724 * @param array<string, mixed> $link Button link data.
1725 *
1726 * @return string
1727 */
1728 protected function build_button_attributes(array $link): string
1729 {
1730 if (empty($link['url'])) {
1731 return '';
1732 }
1733
1734 $attributes = ' href="' . esc_url($link['url']) . '"';
1735 $rels = [];
1736
1737 if (!empty($link['is_external'])) {
1738 $attributes .= ' target="_blank"';
1739 $rels[] = 'noopener';
1740 $rels[] = 'noreferrer';
1741 }
1742
1743 if (!empty($link['nofollow'])) {
1744 $rels[] = 'nofollow';
1745 }
1746
1747 if (!empty($rels)) {
1748 $attributes .= ' rel="' . esc_attr(implode(' ', array_unique($rels))) . '"';
1749 }
1750
1751 return $attributes;
1752 }
1753
1754 /**
1755 * Normalize slider values to numbers.
1756 *
1757 * @param mixed $value Slider value.
1758 * @param float $default Default value.
1759 *
1760 * @return float
1761 */
1762 protected function get_control_number($value, float $default): float
1763 {
1764 if (is_array($value) && isset($value['size'])) {
1765 return is_numeric($value['size']) ? (float) $value['size'] : $default;
1766 }
1767
1768 if (is_numeric($value)) {
1769 return (float) $value;
1770 }
1771
1772 return $default;
1773 }
1774
1775 /**
1776 * Build a slider value with unit for inline CSS.
1777 *
1778 * @param mixed $value Slider value.
1779 * @param string $default_unit Fallback unit.
1780 *
1781 * @return string
1782 */
1783 protected function get_slider_css_value($value, string $default_unit = 'px'): string
1784 {
1785 if (is_array($value) && isset($value['size']) && $value['size'] !== '') {
1786 $unit = isset($value['unit']) && $value['unit'] !== '' ? $value['unit'] : $default_unit;
1787 if (is_numeric($value['size'])) {
1788 return $value['size'] . $unit;
1789 }
1790 }
1791
1792 if (is_numeric($value)) {
1793 return $value . $default_unit;
1794 }
1795
1796 return '';
1797 }
1798
1799 /**
1800 * Render HTML attributes from array.
1801 *
1802 * @param array<string, string> $attributes Attributes list.
1803 *
1804 * @return string
1805 */
1806 protected function render_attribute_string(array $attributes): string
1807 {
1808 $pairs = [];
1809 foreach ($attributes as $key => $value) {
1810 if ($value === '' || $value === null) {
1811 continue;
1812 }
1813 $pairs[] = sprintf('%s="%s"', $key, esc_attr($value));
1814 }
1815
1816 return implode(' ', $pairs);
1817 }
1818
1819 /**
1820 * Sanitize HTML tag.
1821 *
1822 * @param string $tag HTML tag name.
1823 *
1824 * @return string
1825 */
1826 protected function sanitize_html_tag(string $tag): string
1827 {
1828 $allowed = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'span', 'p'];
1829 $tag = strtolower(trim($tag));
1830 return in_array($tag, $allowed, true) ? $tag : 'h3';
1831 }
1832
1833 /**
1834 * Register Pro notice controls.
1835 *
1836 * @return void
1837 */
1838 protected function register_pro_notice_controls(): void
1839 {
1840 if (!king_addons_can_use_pro()) {
1841 Core::renderProFeaturesSection($this, '', Controls_Manager::RAW_HTML, 'parallax-depth-cards', [
1842 'Advanced layer mapping with per-layer controls',
1843 'Dynamic shadow and focus edge highlights',
1844 'Adaptive performance and device toggles',
1845 ]);
1846 }
1847 }
1848 }
1849