PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.44
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.44
51.1.87 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 All 41 releases
king-addons / includes / widgets / Pricing_Calculator / Pricing_Calculator.php

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

2,023 lines 72.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace King_Addons;
4
5 use Elementor\Controls_Manager;
6 use Elementor\Widget_Base;
7 use Elementor\Group_Control_Typography;
8 use Elementor\Group_Control_Background;
9 use Elementor\Group_Control_Box_Shadow;
10 use Elementor\Repeater;
11 use Elementor\Group_Control_Border;
12
13 if (!defined('ABSPATH')) {
14 exit; // Exit if accessed directly.
15 }
16
17
18
19 class Pricing_Calculator extends Widget_Base
20 {
21
22
23 public function get_name(): string
24 {
25 return 'king-addons-pricing-calculator';
26 }
27
28 public function get_title(): string
29 {
30 return esc_html__('Pricing Calculator', 'king-addons');
31 }
32
33 public function get_icon(): string
34 {
35 return 'king-addons-icon king-addons-pricing-calculator';
36 }
37
38 public function get_style_depends(): array
39 {
40 return [KING_ADDONS_ASSETS_UNIQUE_KEY . '-pricing-calculator-style'];
41 }
42
43 public function get_script_depends(): array
44 {
45 return [KING_ADDONS_ASSETS_UNIQUE_KEY . '-pricing-calculator-script'];
46 }
47
48 public function get_categories(): array
49 {
50 return ['king-addons'];
51 }
52
53 public function get_keywords(): array
54 {
55 return [
56 'price',
57 'pricing',
58 'calculator',
59 'pricing calculator',
60 'quote',
61 'estimate',
62 'king addons',
63 'king',
64 'addons',
65 'kingaddons',
66 'king-addons'
67 ];
68 }
69
70 public function get_custom_help_url()
71 {
72 return 'mailto:[email protected]?subject=Bug Report - King Addons&body=Please describe the issue';
73 }
74
75 /**
76 * Register Pro-only controls (placeholder).
77 *
78 * Pro overrides this method to add premium controls without using parent::register_controls().
79 *
80 * @return void
81 */
82 public function register_pro_controls(): void
83 {
84 // Intentionally empty in Free.
85 }
86
87 /**
88 * Filter wrapper classes (placeholder).
89 *
90 * Pro overrides this method to add additional wrapper classes.
91 *
92 * @param array<int, string> $classes Base wrapper classes.
93 * @param array<string, mixed> $settings Widget settings.
94 * @return array<int, string> Filtered wrapper classes.
95 */
96 public function filter_calculator_classes(array $classes, array $settings): array
97 {
98 return $classes;
99 }
100
101 /**
102 * Filter wrapper attributes (placeholder).
103 *
104 * Pro overrides this method to add additional data attributes.
105 *
106 * @param array<string, mixed> $attributes Base wrapper attributes.
107 * @param array<string, mixed> $settings Widget settings.
108 * @return array<string, mixed> Filtered wrapper attributes.
109 */
110 public function filter_calculator_attributes(array $attributes, array $settings): array
111 {
112 return $attributes;
113 }
114
115 /**
116 * Render Pro-only output after the base widget markup (placeholder).
117 *
118 * @param array<string, mixed> $settings Widget settings.
119 * @return void
120 */
121 public function render_pro_after(array $settings): void
122 {
123 // Intentionally empty in Free.
124 }
125
126 protected function register_controls()
127 {
128 $this->start_controls_section(
129 'section_pricing_calculator',
130 [
131 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Pricing Calculator', 'king-addons'),
132 ]
133 );
134
135 if (!king_addons_freemius()->can_use_premium_code__premium_only()) {
136 $this->add_control(
137 'pricing_calculator_pro_notice',
138 [
139 'type' => Controls_Manager::RAW_HTML,
140 'raw' => 'Advanced calculation formulas, conditional logic, and more options are available in the <strong><a href="https://kingaddons.com/pricing/?utm_source=kng-module-pricing-calculator-settings-upgrade-pro&utm_medium=plugin&utm_campaign=kng" target="_blank">Pro version</a></strong>',
141 'content_classes' => 'king-addons-pro-notice',
142 ]
143 );
144 }
145
146 $this->add_control(
147 'calculator_title',
148 [
149 'label' => esc_html__('Calculator Title', 'king-addons'),
150 'type' => Controls_Manager::TEXT,
151 'default' => esc_html__('Pricing Calculator', 'king-addons'),
152 'placeholder' => esc_html__('Enter title', 'king-addons'),
153 'label_block' => true,
154 ]
155 );
156
157 $this->add_control(
158 'calculator_description',
159 [
160 'label' => esc_html__('Description', 'king-addons'),
161 'type' => Controls_Manager::TEXTAREA,
162 'default' => esc_html__('Calculate the cost of your service', 'king-addons'),
163 'placeholder' => esc_html__('Enter description', 'king-addons'),
164 'rows' => 5,
165 ]
166 );
167
168 $this->end_controls_section();
169
170 // Calculator Fields Section
171 $this->start_controls_section(
172 'section_calculator_fields',
173 [
174 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Calculator Fields', 'king-addons'),
175 ]
176 );
177
178 $repeater = new Repeater();
179
180 $repeater->add_control(
181 'field_type',
182 [
183 'label' => esc_html__('Field Type', 'king-addons'),
184 'type' => Controls_Manager::SELECT,
185 'default' => 'number',
186 'options' => [
187 'number' => esc_html__('Number Input', 'king-addons'),
188 'range' => esc_html__('Range Slider', 'king-addons'),
189 'select' => esc_html__('Dropdown Select', 'king-addons'),
190 'radio' => esc_html__('Radio Buttons', 'king-addons'),
191 'checkbox' => esc_html__('Checkbox', 'king-addons'),
192 'switch' => esc_html__('Toggle Switch', 'king-addons')
193 ],
194 ]
195 );
196
197 $repeater->add_control(
198 'field_label',
199 [
200 'label' => esc_html__('Field Label', 'king-addons'),
201 'type' => Controls_Manager::TEXT,
202 'default' => esc_html__('Field Label', 'king-addons'),
203 'label_block' => true,
204 ]
205 );
206
207 $repeater->add_control(
208 'field_id',
209 [
210 'label' => esc_html__('Field ID', 'king-addons'),
211 'type' => Controls_Manager::TEXT,
212 'default' => '',
213 'placeholder' => esc_html__('e.g. quantity, service_type, rush_delivery', 'king-addons'),
214 'label_block' => true,
215 'description' => esc_html__('Set a unique ID for this field to use in formulas and conditions. Leave empty for auto-generated ID.', 'king-addons'),
216 ]
217 );
218
219 $repeater->add_control(
220 'field_description',
221 [
222 'label' => esc_html__('Description', 'king-addons'),
223 'type' => Controls_Manager::TEXT,
224 'default' => '',
225 'label_block' => true,
226 ]
227 );
228
229 $repeater->add_control(
230 'field_unit',
231 [
232 'label' => esc_html__('Unit Label', 'king-addons'),
233 'type' => Controls_Manager::TEXT,
234 'default' => '',
235 'placeholder' => esc_html__('e.g. hours, sq.ft, items', 'king-addons'),
236 'conditions' => [
237 'terms' => [
238 [
239 'name' => 'field_type',
240 'operator' => 'in',
241 'value' => ['number', 'range'],
242 ],
243 ],
244 ],
245 ]
246 );
247
248 $repeater->add_control(
249 'field_min',
250 [
251 'label' => esc_html__('Minimum Value', 'king-addons'),
252 'type' => Controls_Manager::NUMBER,
253 'default' => 0,
254 'conditions' => [
255 'terms' => [
256 [
257 'name' => 'field_type',
258 'operator' => 'in',
259 'value' => ['number', 'range'],
260 ],
261 ],
262 ],
263 ]
264 );
265
266 $repeater->add_control(
267 'field_max',
268 [
269 'label' => esc_html__('Maximum Value', 'king-addons'),
270 'type' => Controls_Manager::NUMBER,
271 'default' => 100,
272 'conditions' => [
273 'terms' => [
274 [
275 'name' => 'field_type',
276 'operator' => 'in',
277 'value' => ['number', 'range'],
278 ],
279 ],
280 ],
281 ]
282 );
283
284 $repeater->add_control(
285 'field_step',
286 [
287 'label' => esc_html__('Step', 'king-addons'),
288 'type' => Controls_Manager::NUMBER,
289 'default' => 1,
290 'min' => 0.01,
291 'conditions' => [
292 'terms' => [
293 [
294 'name' => 'field_type',
295 'operator' => 'in',
296 'value' => ['number', 'range'],
297 ],
298 ],
299 ],
300 ]
301 );
302
303 $repeater->add_control(
304 'field_default',
305 [
306 'label' => esc_html__('Default Value', 'king-addons'),
307 'type' => Controls_Manager::NUMBER,
308 'default' => 0,
309 'conditions' => [
310 'terms' => [
311 [
312 'name' => 'field_type',
313 'operator' => 'in',
314 'value' => ['number', 'range'],
315 ],
316 ],
317 ],
318 ]
319 );
320
321 $repeater->add_control(
322 'field_options',
323 [
324 'label' => esc_html__('Options (Value|Label|Price)', 'king-addons'),
325 'type' => Controls_Manager::TEXTAREA,
326 'default' => "option1|Option 1|10\noption2|Option 2|20\noption3|Option 3|30",
327 'description' => esc_html__('Enter one option per line in format: value|label|price', 'king-addons'),
328 'rows' => 5,
329 'conditions' => [
330 'terms' => [
331 [
332 'name' => 'field_type',
333 'operator' => 'in',
334 'value' => ['select', 'radio'],
335 ],
336 ],
337 ],
338 ]
339 );
340
341 $repeater->add_control(
342 'checkbox_value',
343 [
344 'label' => esc_html__('Checkbox Value', 'king-addons'),
345 'type' => Controls_Manager::NUMBER,
346 'default' => 10,
347 'conditions' => [
348 'terms' => [
349 [
350 'name' => 'field_type',
351 'operator' => 'in',
352 'value' => ['checkbox', 'switch'],
353 ],
354 ],
355 ],
356 ]
357 );
358
359 $repeater->add_control(
360 'field_price_type',
361 [
362 'label' => esc_html__('Price Calculation', 'king-addons'),
363 'type' => Controls_Manager::SELECT,
364 'default' => 'multiply',
365 'options' => [
366 'add' => esc_html__('Add Value', 'king-addons'),
367 'multiply' => esc_html__('Multiply Value', 'king-addons'),
368 'custom' => esc_html__('Custom Formula (Pro)', 'king-addons')
369 ],
370 'description' => esc_html__('Custom formula calculation is available in the Pro version. You can reference fields by their Field ID in custom formulas.', 'king-addons'),
371 ]
372 );
373
374 $repeater->add_control(
375 'field_price',
376 [
377 'label' => esc_html__('Price Amount', 'king-addons'),
378 'type' => Controls_Manager::NUMBER,
379 'default' => 10,
380 'conditions' => [
381 'terms' => [
382 [
383 'name' => 'field_price_type',
384 'operator' => '!==',
385 'value' => 'custom',
386 ],
387 [
388 'name' => 'field_type',
389 'operator' => '!in',
390 'value' => ['select', 'radio'],
391 ],
392 ],
393 ],
394 ]
395 );
396
397 $this->add_control(
398 'calculator_fields',
399 [
400 'label' => esc_html__('Calculator Fields', 'king-addons'),
401 'type' => Controls_Manager::REPEATER,
402 'fields' => $repeater->get_controls(),
403 'default' => [
404 [
405 'field_type' => 'range',
406 'field_label' => esc_html__('Quantity', 'king-addons'),
407 'field_unit' => esc_html__('items', 'king-addons'),
408 'field_min' => 1,
409 'field_max' => 100,
410 'field_step' => 1,
411 'field_default' => 10,
412 'field_price_type' => 'multiply',
413 'field_price' => 10,
414 ],
415 [
416 'field_type' => 'select',
417 'field_label' => esc_html__('Service Type', 'king-addons'),
418 'field_options' => "basic|Basic Service|50\nstandard|Standard Service|100\npremium|Premium Service|150",
419 'field_price_type' => 'add',
420 ],
421 [
422 'field_type' => 'checkbox',
423 'field_label' => esc_html__('Rush Delivery', 'king-addons'),
424 'checkbox_value' => 25,
425 'field_price_type' => 'add',
426 ],
427 ],
428 'title_field' => '{{{ field_label }}}',
429 ]
430 );
431
432 $this->end_controls_section();
433
434 // Calculation Settings Section
435 $this->start_controls_section(
436 'section_calculation_settings',
437 [
438 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Calculation Settings', 'king-addons'),
439 ]
440 );
441
442 $this->add_control(
443 'base_price',
444 [
445 'label' => esc_html__('Base Price', 'king-addons'),
446 'type' => Controls_Manager::NUMBER,
447 'default' => 0,
448 'min' => 0,
449 'step' => 0.01,
450 'description' => esc_html__('Starting price before any calculations', 'king-addons'),
451 ]
452 );
453
454 $this->add_control(
455 'price_prefix',
456 [
457 'label' => esc_html__('Price Prefix', 'king-addons'),
458 'type' => Controls_Manager::TEXT,
459 'default' => '$',
460 'placeholder' => esc_html__('Before price', 'king-addons'),
461 ]
462 );
463
464 $this->add_control(
465 'price_suffix',
466 [
467 'label' => esc_html__('Price Suffix', 'king-addons'),
468 'type' => Controls_Manager::TEXT,
469 'default' => '',
470 'placeholder' => esc_html__('After price', 'king-addons'),
471 ]
472 );
473
474 $this->add_control(
475 'decimal_places',
476 [
477 'label' => esc_html__('Decimal Places', 'king-addons'),
478 'type' => Controls_Manager::NUMBER,
479 'default' => 2,
480 'min' => 0,
481 'max' => 10,
482 'step' => 1,
483 'description' => esc_html__('Number of decimal places to display', 'king-addons'),
484 ]
485 );
486
487 $this->add_control(
488 'thousand_separator',
489 [
490 'label' => esc_html__('Thousand Separator', 'king-addons'),
491 'type' => Controls_Manager::TEXT,
492 'default' => ',',
493 'placeholder' => esc_html__(',', 'king-addons'),
494 ]
495 );
496
497 $this->add_control(
498 'decimal_separator',
499 [
500 'label' => esc_html__('Decimal Separator', 'king-addons'),
501 'type' => Controls_Manager::TEXT,
502 'default' => '.',
503 'placeholder' => esc_html__('.', 'king-addons'),
504 ]
505 );
506
507 $this->add_control(
508 'live_calculation',
509 [
510 'label' => esc_html__('Live Calculation', 'king-addons'),
511 'type' => Controls_Manager::SWITCHER,
512 'label_on' => esc_html__('Yes', 'king-addons'),
513 'label_off' => esc_html__('No', 'king-addons'),
514 'return_value' => 'yes',
515 'default' => 'yes',
516 'description' => esc_html__('Update price automatically when fields change', 'king-addons'),
517 ]
518 );
519
520 $this->add_control(
521 'enable_calculate_button',
522 [
523 'label' => esc_html__('Enable Calculate Button', 'king-addons'),
524 'type' => Controls_Manager::SWITCHER,
525 'label_on' => esc_html__('Yes', 'king-addons'),
526 'label_off' => esc_html__('No', 'king-addons'),
527 'return_value' => 'yes',
528 'default' => 'no',
529 'condition' => [
530 'live_calculation' => '',
531 ],
532 ]
533 );
534
535 $this->add_control(
536 'calculate_button_text',
537 [
538 'label' => esc_html__('Calculate Button Text', 'king-addons'),
539 'type' => Controls_Manager::TEXT,
540 'default' => esc_html__('Calculate', 'king-addons'),
541 'condition' => [
542 'enable_calculate_button' => 'yes',
543 ],
544 ]
545 );
546
547 $this->end_controls_section();
548
549 // Summary Section
550 $this->start_controls_section(
551 'section_summary',
552 [
553 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Summary & Results', 'king-addons'),
554 ]
555 );
556
557 $this->add_control(
558 'show_summary',
559 [
560 'label' => esc_html__('Show Calculation Summary', 'king-addons'),
561 'type' => Controls_Manager::SWITCHER,
562 'label_on' => esc_html__('Yes', 'king-addons'),
563 'label_off' => esc_html__('No', 'king-addons'),
564 'return_value' => 'yes',
565 'default' => 'yes',
566 'description' => esc_html__('Display breakdown of calculation', 'king-addons'),
567 ]
568 );
569
570 $this->add_control(
571 'summary_title',
572 [
573 'label' => esc_html__('Summary Title', 'king-addons'),
574 'type' => Controls_Manager::TEXT,
575 'default' => esc_html__('Summary', 'king-addons'),
576 'condition' => [
577 'show_summary' => 'yes',
578 ],
579 ]
580 );
581
582 $this->add_control(
583 'total_text',
584 [
585 'label' => esc_html__('Total Label', 'king-addons'),
586 'type' => Controls_Manager::TEXT,
587 'default' => esc_html__('Total Price:', 'king-addons'),
588 ]
589 );
590
591 $this->end_controls_section();
592
593 Core::renderProFeaturesSection($this, '', Controls_Manager::RAW_HTML, 'king-addons-pricing-calculator', [
594 'Advanced Formula Calculation',
595 'Conditional Logic',
596 ]);
597
598 // Container Style
599 $this->start_controls_section(
600 'section_container_style',
601 [
602 'label' => esc_html__('Container', 'king-addons'),
603 'tab' => Controls_Manager::TAB_STYLE,
604 ]
605 );
606
607 $this->add_responsive_control(
608 'container_padding',
609 [
610 'label' => esc_html__('Padding', 'king-addons'),
611 'type' => Controls_Manager::DIMENSIONS,
612 'size_units' => ['px', 'em', '%'],
613 'selectors' => [
614 '{{WRAPPER}} .king-pricing-calculator' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
615 ],
616 'default' => [
617 'top' => '30',
618 'right' => '30',
619 'bottom' => '30',
620 'left' => '30',
621 'unit' => 'px',
622 'isLinked' => true,
623 ],
624 ]
625 );
626
627 $this->add_responsive_control(
628 'container_margin',
629 [
630 'label' => esc_html__('Margin', 'king-addons'),
631 'type' => Controls_Manager::DIMENSIONS,
632 'size_units' => ['px', 'em', '%'],
633 'selectors' => [
634 '{{WRAPPER}} .king-pricing-calculator' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
635 ],
636 ]
637 );
638
639 $this->add_group_control(
640 Group_Control_Background::get_type(),
641 [
642 'name' => 'container_background',
643 'label' => esc_html__('Background', 'king-addons'),
644 'types' => ['classic', 'gradient'],
645 'selector' => '{{WRAPPER}} .king-pricing-calculator',
646 ]
647 );
648
649 $this->add_group_control(
650 Group_Control_Border::get_type(),
651 [
652 'name' => 'container_border',
653 'label' => esc_html__('Border', 'king-addons'),
654 'selector' => '{{WRAPPER}} .king-pricing-calculator',
655 ]
656 );
657
658 $this->add_responsive_control(
659 'container_border_radius',
660 [
661 'label' => esc_html__('Border Radius', 'king-addons'),
662 'type' => Controls_Manager::DIMENSIONS,
663 'size_units' => ['px', '%'],
664 'selectors' => [
665 '{{WRAPPER}} .king-pricing-calculator' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
666 ],
667 ]
668 );
669
670 $this->add_group_control(
671 Group_Control_Box_Shadow::get_type(),
672 [
673 'name' => 'container_box_shadow',
674 'label' => esc_html__('Box Shadow', 'king-addons'),
675 'selector' => '{{WRAPPER}} .king-pricing-calculator',
676 ]
677 );
678
679
680
681
682 $this->end_controls_section();
683
684
685
686
687 // Title & Description Style
688 $this->start_controls_section(
689 'section_title_style',
690 [
691 'label' => esc_html__('Title & Description', 'king-addons'),
692 'tab' => Controls_Manager::TAB_STYLE,
693 ]
694 );
695
696 $this->add_control(
697 'title_color',
698 [
699 'label' => esc_html__('Title Color', 'king-addons'),
700 'type' => Controls_Manager::COLOR,
701 'selectors' => [
702 '{{WRAPPER}} .king-pricing-calculator__title' => 'color: {{VALUE}};',
703 ],
704 ]
705 );
706
707 $this->add_group_control(
708 Group_Control_Typography::get_type(),
709 [
710 'name' => 'title_typography',
711 'selector' => '{{WRAPPER}} .king-pricing-calculator__title',
712 ]
713 );
714
715 $this->add_responsive_control(
716 'title_margin',
717 [
718 'label' => esc_html__('Title Margin', 'king-addons'),
719 'type' => Controls_Manager::DIMENSIONS,
720 'size_units' => ['px', 'em', '%'],
721 'selectors' => [
722 '{{WRAPPER}} .king-pricing-calculator__title' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
723 ],
724 ]
725 );
726
727 $this->add_control(
728 'description_color',
729 [
730 'label' => esc_html__('Description Color', 'king-addons'),
731 'type' => Controls_Manager::COLOR,
732 'selectors' => [
733 '{{WRAPPER}} .king-pricing-calculator__description' => 'color: {{VALUE}};',
734 ],
735 ]
736 );
737
738 $this->add_group_control(
739 Group_Control_Typography::get_type(),
740 [
741 'name' => 'description_typography',
742 'selector' => '{{WRAPPER}} .king-pricing-calculator__description',
743 ]
744 );
745
746 $this->add_responsive_control(
747 'description_margin',
748 [
749 'label' => esc_html__('Description Margin', 'king-addons'),
750 'type' => Controls_Manager::DIMENSIONS,
751 'size_units' => ['px', 'em', '%'],
752 'selectors' => [
753 '{{WRAPPER}} .king-pricing-calculator__description' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
754 ],
755 ]
756 );
757
758 $this->end_controls_section();
759
760 // Fields Style
761 $this->start_controls_section(
762 'section_fields_style',
763 [
764 'label' => esc_html__('Fields', 'king-addons'),
765 'tab' => Controls_Manager::TAB_STYLE,
766 ]
767 );
768
769 $this->add_responsive_control(
770 'fields_spacing',
771 [
772 'label' => esc_html__('Fields Spacing', 'king-addons'),
773 'type' => Controls_Manager::SLIDER,
774 'size_units' => ['px', 'em'],
775 'range' => [
776 'px' => [
777 'min' => 0,
778 'max' => 100,
779 ],
780 'em' => [
781 'min' => 0,
782 'max' => 10,
783 ],
784 ],
785 'default' => [
786 'unit' => 'px',
787 'size' => 20,
788 ],
789 'selectors' => [
790 '{{WRAPPER}} .king-pricing-calculator__field:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}};',
791 ],
792 ]
793 );
794
795 $this->add_control(
796 'field_label_heading',
797 [
798 'label' => esc_html__('Field Labels', 'king-addons'),
799 'type' => Controls_Manager::HEADING,
800 'separator' => 'before',
801 ]
802 );
803
804 $this->add_control(
805 'field_label_color',
806 [
807 'label' => esc_html__('Label Color', 'king-addons'),
808 'type' => Controls_Manager::COLOR,
809 'selectors' => [
810 '{{WRAPPER}} .king-pricing-calculator__field-label' => 'color: {{VALUE}};',
811 ],
812 ]
813 );
814
815 $this->add_group_control(
816 Group_Control_Typography::get_type(),
817 [
818 'name' => 'field_label_typography',
819 'selector' => '{{WRAPPER}} .king-pricing-calculator__field-label',
820 ]
821 );
822
823 $this->add_responsive_control(
824 'field_label_margin',
825 [
826 'label' => esc_html__('Label Margin', 'king-addons'),
827 'type' => Controls_Manager::DIMENSIONS,
828 'size_units' => ['px', 'em', '%'],
829 'selectors' => [
830 '{{WRAPPER}} .king-pricing-calculator__field-label' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
831 ],
832 'default' => [
833 'top' => '0',
834 'right' => '0',
835 'bottom' => '5',
836 'left' => '0',
837 'unit' => 'px',
838 'isLinked' => false,
839 ],
840 ]
841 );
842
843 $this->add_control(
844 'field_description_color',
845 [
846 'label' => esc_html__('Description Color', 'king-addons'),
847 'type' => Controls_Manager::COLOR,
848 'selectors' => [
849 '{{WRAPPER}} .king-pricing-calculator__field-description' => 'color: {{VALUE}};',
850 ],
851 ]
852 );
853
854 $this->add_group_control(
855 Group_Control_Typography::get_type(),
856 [
857 'name' => 'field_description_typography',
858 'selector' => '{{WRAPPER}} .king-pricing-calculator__field-description',
859 ]
860 );
861
862 $this->add_responsive_control(
863 'field_description_margin',
864 [
865 'label' => esc_html__('Description Margin', 'king-addons'),
866 'type' => Controls_Manager::DIMENSIONS,
867 'size_units' => ['px', 'em', '%'],
868 'selectors' => [
869 '{{WRAPPER}} .king-pricing-calculator__field-description' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
870 ],
871 ]
872 );
873
874 $this->add_control(
875 'input_fields_heading',
876 [
877 'label' => esc_html__('Input Fields', 'king-addons'),
878 'type' => Controls_Manager::HEADING,
879 'separator' => 'before',
880 ]
881 );
882
883 $this->add_responsive_control(
884 'input_padding',
885 [
886 'label' => esc_html__('Input Padding', 'king-addons'),
887 'type' => Controls_Manager::DIMENSIONS,
888 'size_units' => ['px', 'em', '%'],
889 'selectors' => [
890 '{{WRAPPER}} .king-pricing-calculator__field input[type="number"],
891 {{WRAPPER}} .king-pricing-calculator__field select' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
892 ],
893 ]
894 );
895
896 $this->start_controls_tabs('input_style_tabs');
897
898 $this->start_controls_tab(
899 'input_normal_tab',
900 [
901 'label' => esc_html__('Normal', 'king-addons'),
902 ]
903 );
904
905 $this->add_control(
906 'input_text_color',
907 [
908 'label' => esc_html__('Text Color', 'king-addons'),
909 'type' => Controls_Manager::COLOR,
910 'selectors' => [
911 '{{WRAPPER}} .king-pricing-calculator__field input,
912 {{WRAPPER}} .king-pricing-calculator__field select,
913 {{WRAPPER}} .king-pricing-calculator__field input::placeholder' => 'color: {{VALUE}};',
914 ],
915 ]
916 );
917
918 $this->add_control(
919 'input_background_color',
920 [
921 'label' => esc_html__('Background Color', 'king-addons'),
922 'type' => Controls_Manager::COLOR,
923 'selectors' => [
924 '{{WRAPPER}} .king-pricing-calculator__field input,
925 {{WRAPPER}} .king-pricing-calculator__field select' => 'background-color: {{VALUE}};',
926 ],
927 ]
928 );
929
930 $this->add_group_control(
931 Group_Control_Border::get_type(),
932 [
933 'name' => 'input_border',
934 'label' => esc_html__('Border', 'king-addons'),
935 'selector' => '{{WRAPPER}} .king-pricing-calculator__field input,
936 {{WRAPPER}} .king-pricing-calculator__field select',
937 ]
938 );
939
940 $this->add_responsive_control(
941 'input_border_radius',
942 [
943 'label' => esc_html__('Border Radius', 'king-addons'),
944 'type' => Controls_Manager::DIMENSIONS,
945 'size_units' => ['px', '%'],
946 'selectors' => [
947 '{{WRAPPER}} .king-pricing-calculator__field input,
948 {{WRAPPER}} .king-pricing-calculator__field select' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
949 ],
950 ]
951 );
952
953 $this->add_group_control(
954 Group_Control_Box_Shadow::get_type(),
955 [
956 'name' => 'input_box_shadow',
957 'selector' => '{{WRAPPER}} .king-pricing-calculator__field input,
958 {{WRAPPER}} .king-pricing-calculator__field select',
959 ]
960 );
961
962 $this->end_controls_tab();
963
964 $this->start_controls_tab(
965 'input_focus_tab',
966 [
967 'label' => esc_html__('Focus', 'king-addons'),
968 ]
969 );
970
971 $this->add_control(
972 'input_focus_text_color',
973 [
974 'label' => esc_html__('Text Color', 'king-addons'),
975 'type' => Controls_Manager::COLOR,
976 'selectors' => [
977 '{{WRAPPER}} .king-pricing-calculator__field input:focus,
978 {{WRAPPER}} .king-pricing-calculator__field select:focus' => 'color: {{VALUE}};',
979 ],
980 ]
981 );
982
983 $this->add_control(
984 'input_focus_background_color',
985 [
986 'label' => esc_html__('Background Color', 'king-addons'),
987 'type' => Controls_Manager::COLOR,
988 'selectors' => [
989 '{{WRAPPER}} .king-pricing-calculator__field input:focus,
990 {{WRAPPER}} .king-pricing-calculator__field select:focus' => 'background-color: {{VALUE}};',
991 ],
992 ]
993 );
994
995 $this->add_control(
996 'input_focus_border_color',
997 [
998 'label' => esc_html__('Border Color', 'king-addons'),
999 'type' => Controls_Manager::COLOR,
1000 'selectors' => [
1001 '{{WRAPPER}} .king-pricing-calculator__field input:focus,
1002 {{WRAPPER}} .king-pricing-calculator__field select:focus' => 'border-color: {{VALUE}};',
1003 ],
1004 ]
1005 );
1006
1007 $this->add_group_control(
1008 Group_Control_Box_Shadow::get_type(),
1009 [
1010 'name' => 'input_focus_box_shadow',
1011 'selector' => '{{WRAPPER}} .king-pricing-calculator__field input:focus,
1012 {{WRAPPER}} .king-pricing-calculator__field select:focus',
1013 ]
1014 );
1015
1016 $this->end_controls_tab();
1017
1018 $this->end_controls_tabs();
1019
1020 $this->add_group_control(
1021 Group_Control_Typography::get_type(),
1022 [
1023 'name' => 'input_typography',
1024 'selector' => '{{WRAPPER}} .king-pricing-calculator__field input,
1025 {{WRAPPER}} .king-pricing-calculator__field select,
1026 {{WRAPPER}} .king-pricing-calculator__field-unit',
1027 'separator' => 'before',
1028 ]
1029 );
1030
1031 $this->add_control(
1032 'range_slider_heading',
1033 [
1034 'label' => esc_html__('Range Slider', 'king-addons'),
1035 'type' => Controls_Manager::HEADING,
1036 'separator' => 'before',
1037 ]
1038 );
1039
1040 $this->add_control(
1041 'range_slider_track_color',
1042 [
1043 'label' => esc_html__('Track Color', 'king-addons'),
1044 'type' => Controls_Manager::COLOR,
1045 'selectors' => [
1046 '{{WRAPPER}} .king-pricing-calculator__field input[type="range"]' => '--track-color: {{VALUE}};',
1047 ],
1048 ]
1049 );
1050
1051 $this->add_control(
1052 'range_slider_progress_color',
1053 [
1054 'label' => esc_html__('Progress Color', 'king-addons'),
1055 'type' => Controls_Manager::COLOR,
1056 'selectors' => [
1057 '{{WRAPPER}} .king-pricing-calculator__field input[type="range"]' => '--progress-color: {{VALUE}};',
1058 ],
1059 ]
1060 );
1061
1062 $this->add_control(
1063 'range_slider_thumb_color',
1064 [
1065 'label' => esc_html__('Thumb Color', 'king-addons'),
1066 'type' => Controls_Manager::COLOR,
1067 'selectors' => [
1068 '{{WRAPPER}} .king-pricing-calculator__field input[type="range"]' => '--thumb-color: {{VALUE}};',
1069 ],
1070 ]
1071 );
1072
1073 $this->add_responsive_control(
1074 'range_slider_track_height',
1075 [
1076 'label' => esc_html__('Track Height', 'king-addons'),
1077 'type' => Controls_Manager::SLIDER,
1078 'size_units' => ['px'],
1079 'range' => [
1080 'px' => [
1081 'min' => 1,
1082 'max' => 20,
1083 ],
1084 ],
1085 'selectors' => [
1086 '{{WRAPPER}} .king-pricing-calculator__field input[type="range"]' => '--track-height: {{SIZE}}{{UNIT}};',
1087 ],
1088 ]
1089 );
1090
1091 $this->add_responsive_control(
1092 'range_slider_thumb_size',
1093 [
1094 'label' => esc_html__('Thumb Size', 'king-addons'),
1095 'type' => Controls_Manager::SLIDER,
1096 'size_units' => ['px'],
1097 'range' => [
1098 'px' => [
1099 'min' => 10,
1100 'max' => 40,
1101 ],
1102 ],
1103 'selectors' => [
1104 '{{WRAPPER}} .king-pricing-calculator__field input[type="range"]' => '--thumb-size: {{SIZE}}{{UNIT}};',
1105 ],
1106 ]
1107 );
1108
1109 $this->end_controls_section();
1110
1111 // Calculate Button Style
1112 $this->start_controls_section(
1113 'section_button_style',
1114 [
1115 'label' => esc_html__('Calculate Button', 'king-addons'),
1116 'tab' => Controls_Manager::TAB_STYLE,
1117 'condition' => [
1118 'enable_calculate_button' => 'yes',
1119 ],
1120 ]
1121 );
1122
1123 $this->add_group_control(
1124 Group_Control_Typography::get_type(),
1125 [
1126 'name' => 'button_typography',
1127 'selector' => '{{WRAPPER}} .king-pricing-calculator__calculate-button',
1128 ]
1129 );
1130
1131 $this->add_responsive_control(
1132 'button_padding',
1133 [
1134 'label' => esc_html__('Padding', 'king-addons'),
1135 'type' => Controls_Manager::DIMENSIONS,
1136 'size_units' => ['px', 'em', '%'],
1137 'selectors' => [
1138 '{{WRAPPER}} .king-pricing-calculator__calculate-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1139 ],
1140 ]
1141 );
1142
1143 $this->add_responsive_control(
1144 'button_margin',
1145 [
1146 'label' => esc_html__('Margin', 'king-addons'),
1147 'type' => Controls_Manager::DIMENSIONS,
1148 'size_units' => ['px', 'em', '%'],
1149 'selectors' => [
1150 '{{WRAPPER}} .king-pricing-calculator__calculate-button-wrapper' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1151 ],
1152 'default' => [
1153 'top' => '20',
1154 'right' => '0',
1155 'bottom' => '20',
1156 'left' => '0',
1157 'unit' => 'px',
1158 'isLinked' => false,
1159 ],
1160 ]
1161 );
1162
1163 $this->start_controls_tabs('button_style_tabs');
1164
1165 $this->start_controls_tab(
1166 'button_normal_tab',
1167 [
1168 'label' => esc_html__('Normal', 'king-addons'),
1169 ]
1170 );
1171
1172 $this->add_control(
1173 'button_text_color',
1174 [
1175 'label' => esc_html__('Text Color', 'king-addons'),
1176 'type' => Controls_Manager::COLOR,
1177 'selectors' => [
1178 '{{WRAPPER}} .king-pricing-calculator__calculate-button' => 'color: {{VALUE}};',
1179 ],
1180 'default' => '#ffffff',
1181 ]
1182 );
1183
1184 $this->add_group_control(
1185 Group_Control_Background::get_type(),
1186 [
1187 'name' => 'button_background',
1188 'label' => esc_html__('Background', 'king-addons'),
1189 'types' => ['classic', 'gradient'],
1190 'exclude' => ['image'],
1191 'selector' => '{{WRAPPER}} .king-pricing-calculator__calculate-button',
1192 'fields_options' => [
1193 'background' => [
1194 'default' => 'classic',
1195 ],
1196 'color' => [
1197 'default' => '#5cb85c',
1198 ],
1199 ],
1200 ]
1201 );
1202
1203 $this->add_group_control(
1204 Group_Control_Border::get_type(),
1205 [
1206 'name' => 'button_border',
1207 'label' => esc_html__('Border', 'king-addons'),
1208 'selector' => '{{WRAPPER}} .king-pricing-calculator__calculate-button',
1209 ]
1210 );
1211
1212 $this->add_responsive_control(
1213 'button_border_radius',
1214 [
1215 'label' => esc_html__('Border Radius', 'king-addons'),
1216 'type' => Controls_Manager::DIMENSIONS,
1217 'size_units' => ['px', '%'],
1218 'selectors' => [
1219 '{{WRAPPER}} .king-pricing-calculator__calculate-button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1220 ],
1221 ]
1222 );
1223
1224 $this->add_group_control(
1225 Group_Control_Box_Shadow::get_type(),
1226 [
1227 'name' => 'button_box_shadow',
1228 'selector' => '{{WRAPPER}} .king-pricing-calculator__calculate-button',
1229 ]
1230 );
1231
1232 $this->end_controls_tab();
1233
1234 $this->start_controls_tab(
1235 'button_hover_tab',
1236 [
1237 'label' => esc_html__('Hover', 'king-addons'),
1238 ]
1239 );
1240
1241 $this->add_control(
1242 'button_hover_text_color',
1243 [
1244 'label' => esc_html__('Text Color', 'king-addons'),
1245 'type' => Controls_Manager::COLOR,
1246 'selectors' => [
1247 '{{WRAPPER}} .king-pricing-calculator__calculate-button:hover' => 'color: {{VALUE}};',
1248 ],
1249 ]
1250 );
1251
1252 $this->add_group_control(
1253 Group_Control_Background::get_type(),
1254 [
1255 'name' => 'button_hover_background',
1256 'label' => esc_html__('Background', 'king-addons'),
1257 'types' => ['classic', 'gradient'],
1258 'exclude' => ['image'],
1259 'selector' => '{{WRAPPER}} .king-pricing-calculator__calculate-button:hover',
1260 'fields_options' => [
1261 'background' => [
1262 'default' => 'classic',
1263 ],
1264 'color' => [
1265 'default' => '#449d44',
1266 ],
1267 ],
1268 ]
1269 );
1270
1271 $this->add_control(
1272 'button_hover_border_color',
1273 [
1274 'label' => esc_html__('Border Color', 'king-addons'),
1275 'type' => Controls_Manager::COLOR,
1276 'selectors' => [
1277 '{{WRAPPER}} .king-pricing-calculator__calculate-button:hover' => 'border-color: {{VALUE}};',
1278 ],
1279 'condition' => [
1280 'button_border_border!' => '',
1281 ],
1282 ]
1283 );
1284
1285 $this->add_group_control(
1286 Group_Control_Box_Shadow::get_type(),
1287 [
1288 'name' => 'button_hover_box_shadow',
1289 'selector' => '{{WRAPPER}} .king-pricing-calculator__calculate-button:hover',
1290 ]
1291 );
1292
1293 $this->add_control(
1294 'button_hover_transition',
1295 [
1296 'label' => esc_html__('Transition Duration', 'king-addons'),
1297 'type' => Controls_Manager::SLIDER,
1298 'default' => [
1299 'size' => 0.3,
1300 ],
1301 'range' => [
1302 'px' => [
1303 'max' => 3,
1304 'step' => 0.1,
1305 ],
1306 ],
1307 'selectors' => [
1308 '{{WRAPPER}} .king-pricing-calculator__calculate-button' => 'transition: all {{SIZE}}s ease;',
1309 ],
1310 ]
1311 );
1312
1313 $this->end_controls_tab();
1314
1315 $this->end_controls_tabs();
1316
1317 $this->end_controls_section();
1318
1319 // Summary Style
1320 $this->start_controls_section(
1321 'section_summary_style',
1322 [
1323 'label' => esc_html__('Summary & Results', 'king-addons'),
1324 'tab' => Controls_Manager::TAB_STYLE,
1325 ]
1326 );
1327
1328 $this->add_control(
1329 'summary_title_color',
1330 [
1331 'label' => esc_html__('Summary Title Color', 'king-addons'),
1332 'type' => Controls_Manager::COLOR,
1333 'selectors' => [
1334 '{{WRAPPER}} .king-pricing-calculator__summary-title' => 'color: {{VALUE}};',
1335 ],
1336 'condition' => [
1337 'show_summary' => 'yes',
1338 ],
1339 ]
1340 );
1341
1342 $this->add_group_control(
1343 Group_Control_Typography::get_type(),
1344 [
1345 'name' => 'summary_title_typography',
1346 'selector' => '{{WRAPPER}} .king-pricing-calculator__summary-title',
1347 'condition' => [
1348 'show_summary' => 'yes',
1349 ],
1350 ]
1351 );
1352
1353 $this->add_responsive_control(
1354 'summary_title_margin',
1355 [
1356 'label' => esc_html__('Summary Title Margin', 'king-addons'),
1357 'type' => Controls_Manager::DIMENSIONS,
1358 'size_units' => ['px', 'em', '%'],
1359 'selectors' => [
1360 '{{WRAPPER}} .king-pricing-calculator__summary-title' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1361 ],
1362 'condition' => [
1363 'show_summary' => 'yes',
1364 ],
1365 ]
1366 );
1367
1368 $this->add_control(
1369 'summary_container_heading',
1370 [
1371 'label' => esc_html__('Summary Container', 'king-addons'),
1372 'type' => Controls_Manager::HEADING,
1373 'separator' => 'before',
1374 'condition' => [
1375 'show_summary' => 'yes',
1376 ],
1377 ]
1378 );
1379
1380 $this->add_group_control(
1381 Group_Control_Background::get_type(),
1382 [
1383 'name' => 'summary_background',
1384 'label' => esc_html__('Background', 'king-addons'),
1385 'types' => ['classic', 'gradient'],
1386 'selector' => '{{WRAPPER}} .king-pricing-calculator__summary',
1387 'condition' => [
1388 'show_summary' => 'yes',
1389 ],
1390 ]
1391 );
1392
1393 $this->add_group_control(
1394 Group_Control_Border::get_type(),
1395 [
1396 'name' => 'summary_border',
1397 'label' => esc_html__('Border', 'king-addons'),
1398 'selector' => '{{WRAPPER}} .king-pricing-calculator__summary',
1399 'condition' => [
1400 'show_summary' => 'yes',
1401 ],
1402 ]
1403 );
1404
1405 $this->add_responsive_control(
1406 'summary_border_radius',
1407 [
1408 'label' => esc_html__('Border Radius', 'king-addons'),
1409 'type' => Controls_Manager::DIMENSIONS,
1410 'size_units' => ['px', '%'],
1411 'selectors' => [
1412 '{{WRAPPER}} .king-pricing-calculator__summary' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1413 ],
1414 'condition' => [
1415 'show_summary' => 'yes',
1416 ],
1417 ]
1418 );
1419
1420 $this->add_responsive_control(
1421 'summary_padding',
1422 [
1423 'label' => esc_html__('Padding', 'king-addons'),
1424 'type' => Controls_Manager::DIMENSIONS,
1425 'size_units' => ['px', 'em', '%'],
1426 'selectors' => [
1427 '{{WRAPPER}} .king-pricing-calculator__summary' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1428 ],
1429 'condition' => [
1430 'show_summary' => 'yes',
1431 ],
1432 'default' => [
1433 'top' => '15',
1434 'right' => '15',
1435 'bottom' => '15',
1436 'left' => '15',
1437 'unit' => 'px',
1438 'isLinked' => true,
1439 ],
1440 ]
1441 );
1442
1443 $this->add_responsive_control(
1444 'summary_margin',
1445 [
1446 'label' => esc_html__('Margin', 'king-addons'),
1447 'type' => Controls_Manager::DIMENSIONS,
1448 'size_units' => ['px', 'em', '%'],
1449 'selectors' => [
1450 '{{WRAPPER}} .king-pricing-calculator__summary' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1451 ],
1452 'condition' => [
1453 'show_summary' => 'yes',
1454 ],
1455 'default' => [
1456 'top' => '20',
1457 'right' => '0',
1458 'bottom' => '0',
1459 'left' => '0',
1460 'unit' => 'px',
1461 'isLinked' => false,
1462 ],
1463 ]
1464 );
1465
1466 $this->add_control(
1467 'summary_item_heading',
1468 [
1469 'label' => esc_html__('Summary Items', 'king-addons'),
1470 'type' => Controls_Manager::HEADING,
1471 'separator' => 'before',
1472 'condition' => [
1473 'show_summary' => 'yes',
1474 ],
1475 ]
1476 );
1477
1478 $this->add_control(
1479 'summary_item_color',
1480 [
1481 'label' => esc_html__('Item Text Color', 'king-addons'),
1482 'type' => Controls_Manager::COLOR,
1483 'selectors' => [
1484 '{{WRAPPER}} .king-pricing-calculator__summary-item' => 'color: {{VALUE}};',
1485 ],
1486 'condition' => [
1487 'show_summary' => 'yes',
1488 ],
1489 ]
1490 );
1491
1492 $this->add_group_control(
1493 Group_Control_Typography::get_type(),
1494 [
1495 'name' => 'summary_item_typography',
1496 'selector' => '{{WRAPPER}} .king-pricing-calculator__summary-item',
1497 'condition' => [
1498 'show_summary' => 'yes',
1499 ],
1500 ]
1501 );
1502
1503 $this->add_responsive_control(
1504 'summary_item_spacing',
1505 [
1506 'label' => esc_html__('Item Spacing', 'king-addons'),
1507 'type' => Controls_Manager::SLIDER,
1508 'size_units' => ['px', 'em'],
1509 'range' => [
1510 'px' => [
1511 'min' => 0,
1512 'max' => 50,
1513 ],
1514 'em' => [
1515 'min' => 0,
1516 'max' => 5,
1517 ],
1518 ],
1519 'selectors' => [
1520 '{{WRAPPER}} .king-pricing-calculator__summary-item:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}};',
1521 ],
1522 'condition' => [
1523 'show_summary' => 'yes',
1524 ],
1525 ]
1526 );
1527
1528 $this->add_control(
1529 'total_heading',
1530 [
1531 'label' => esc_html__('Total Price', 'king-addons'),
1532 'type' => Controls_Manager::HEADING,
1533 'separator' => 'before',
1534 ]
1535 );
1536
1537 $this->add_control(
1538 'total_label_color',
1539 [
1540 'label' => esc_html__('Total Label Color', 'king-addons'),
1541 'type' => Controls_Manager::COLOR,
1542 'selectors' => [
1543 '{{WRAPPER}} .king-pricing-calculator__total-label' => 'color: {{VALUE}};',
1544 ],
1545 ]
1546 );
1547
1548 $this->add_group_control(
1549 Group_Control_Typography::get_type(),
1550 [
1551 'name' => 'total_label_typography',
1552 'selector' => '{{WRAPPER}} .king-pricing-calculator__total-label',
1553 ]
1554 );
1555
1556 $this->add_control(
1557 'total_price_color',
1558 [
1559 'label' => esc_html__('Total Price Color', 'king-addons'),
1560 'type' => Controls_Manager::COLOR,
1561 'selectors' => [
1562 '{{WRAPPER}} .king-pricing-calculator__total-price' => 'color: {{VALUE}};',
1563 ],
1564 ]
1565 );
1566
1567 $this->add_group_control(
1568 Group_Control_Typography::get_type(),
1569 [
1570 'name' => 'total_price_typography',
1571 'selector' => '{{WRAPPER}} .king-pricing-calculator__total-price',
1572 ]
1573 );
1574
1575 $this->add_group_control(
1576 Group_Control_Background::get_type(),
1577 [
1578 'name' => 'total_background',
1579 'label' => esc_html__('Background', 'king-addons'),
1580 'types' => ['classic', 'gradient'],
1581 'selector' => '{{WRAPPER}} .king-pricing-calculator__total',
1582 ]
1583 );
1584
1585 $this->add_group_control(
1586 Group_Control_Border::get_type(),
1587 [
1588 'name' => 'total_border',
1589 'label' => esc_html__('Border', 'king-addons'),
1590 'selector' => '{{WRAPPER}} .king-pricing-calculator__total',
1591 ]
1592 );
1593
1594 $this->add_responsive_control(
1595 'total_border_radius',
1596 [
1597 'label' => esc_html__('Border Radius', 'king-addons'),
1598 'type' => Controls_Manager::DIMENSIONS,
1599 'size_units' => ['px', '%'],
1600 'selectors' => [
1601 '{{WRAPPER}} .king-pricing-calculator__total' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1602 ],
1603 ]
1604 );
1605
1606 $this->add_responsive_control(
1607 'total_padding',
1608 [
1609 'label' => esc_html__('Padding', 'king-addons'),
1610 'type' => Controls_Manager::DIMENSIONS,
1611 'size_units' => ['px', 'em', '%'],
1612 'selectors' => [
1613 '{{WRAPPER}} .king-pricing-calculator__total' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1614 ],
1615 'default' => [
1616 'top' => '15',
1617 'right' => '15',
1618 'bottom' => '15',
1619 'left' => '15',
1620 'unit' => 'px',
1621 'isLinked' => true,
1622 ],
1623 ]
1624 );
1625
1626 $this->add_responsive_control(
1627 'total_margin',
1628 [
1629 'label' => esc_html__('Margin', 'king-addons'),
1630 'type' => Controls_Manager::DIMENSIONS,
1631 'size_units' => ['px', 'em', '%'],
1632 'selectors' => [
1633 '{{WRAPPER}} .king-pricing-calculator__total' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
1634 ],
1635 'default' => [
1636 'top' => '20',
1637 'right' => '0',
1638 'bottom' => '0',
1639 'left' => '0',
1640 'unit' => 'px',
1641 'isLinked' => false,
1642 ],
1643 ]
1644 );
1645
1646 $this->end_controls_section();
1647
1648 // Allow Pro to add additional controls without using parent::register_controls().
1649 $this->register_pro_controls();
1650 }
1651
1652 /**
1653 * Format a number with proper separators
1654 *
1655 * @param float $number The number to format
1656 * @param array $settings Widget settings
1657 * @return string Formatted number
1658 */
1659 protected function format_number($number, $settings)
1660 {
1661 $decimal_places = intval($settings['decimal_places']);
1662 // Sanitize separators to prevent XSS
1663 $thousand_separator = wp_strip_all_tags($settings['thousand_separator']);
1664 $decimal_separator = wp_strip_all_tags($settings['decimal_separator']);
1665
1666 return number_format($number, $decimal_places, $decimal_separator, $thousand_separator);
1667 }
1668
1669 /**
1670 * Render field based on its type
1671 *
1672 * @param array $field Field settings
1673 * @param string $field_id Unique field ID
1674 * @return string HTML markup for the field
1675 */
1676 protected function render_field($field, $field_id)
1677 {
1678 $html = '<div class="king-pricing-calculator__field" data-field-id="' . esc_attr($field_id) . '" data-field-type="' . esc_attr($field['field_type']) . '" data-price-type="' . esc_attr($field['field_price_type']) . '"';
1679
1680 switch ($field['field_type']) {
1681 case 'number':
1682 case 'range':
1683 $html .= ' data-price="' . esc_attr($field['field_price']) . '"';
1684 break;
1685
1686 case 'checkbox':
1687 case 'switch':
1688 $html .= ' data-price="' . esc_attr($field['checkbox_value']) . '"';
1689 break;
1690 }
1691
1692 $html .= '>';
1693
1694 // Field Label
1695 if (!empty($field['field_label'])) {
1696 $html .= '<label class="king-pricing-calculator__field-label" for="' . esc_attr($field_id) . '">' . esc_html($field['field_label']) . '</label>';
1697 }
1698
1699 // Field Description
1700 if (!empty($field['field_description'])) {
1701 $html .= '<div class="king-pricing-calculator__field-description" id="' . esc_attr($field_id) . '-desc">' . esc_html($field['field_description']) . '</div>';
1702 }
1703
1704 // Field Input
1705 $html .= '<div class="king-pricing-calculator__field-input">';
1706
1707 switch ($field['field_type']) {
1708 case 'number':
1709 $html .= $this->render_number_field($field, $field_id);
1710 break;
1711
1712 case 'range':
1713 $html .= $this->render_range_field($field, $field_id);
1714 break;
1715
1716 case 'select':
1717 $html .= $this->render_select_field($field, $field_id);
1718 break;
1719
1720 case 'radio':
1721 $html .= $this->render_radio_field($field, $field_id);
1722 break;
1723
1724 case 'checkbox':
1725 $html .= $this->render_checkbox_field($field, $field_id);
1726 break;
1727
1728 case 'switch':
1729 $html .= $this->render_switch_field($field, $field_id);
1730 break;
1731 }
1732
1733 $html .= '</div></div>';
1734
1735 return $html;
1736 }
1737
1738 /**
1739 * Render a number input field
1740 *
1741 * @param array $field Field settings
1742 * @param string $field_id Unique field ID
1743 * @return string HTML markup for number field
1744 */
1745 protected function render_number_field($field, $field_id)
1746 {
1747 $desc_id = !empty($field['field_description']) ? $field_id . '-desc' : '';
1748 $aria_desc = !empty($desc_id) ? ' aria-describedby="' . esc_attr($desc_id) . '"' : '';
1749
1750 $html = '<div class="king-pricing-calculator__number-field">';
1751 $html .= '<input type="number" id="' . esc_attr($field_id) . '" name="' . esc_attr($field_id) . '"';
1752 $html .= ' min="' . esc_attr($field['field_min']) . '" max="' . esc_attr($field['field_max']) . '" step="' . esc_attr($field['field_step']) . '"';
1753 $html .= ' value="' . esc_attr($field['field_default']) . '"';
1754 $html .= ' class="king-pricing-calculator__input"' . $aria_desc . '>';
1755
1756 if (!empty($field['field_unit'])) {
1757 $html .= '<span class="king-pricing-calculator__field-unit" aria-hidden="true">' . esc_html($field['field_unit']) . '</span>';
1758 }
1759
1760 $html .= '</div>';
1761
1762 return $html;
1763 }
1764
1765 /**
1766 * Render a range slider field
1767 *
1768 * @param array $field Field settings
1769 * @param string $field_id Unique field ID
1770 * @return string HTML markup for range field
1771 */
1772 protected function render_range_field($field, $field_id)
1773 {
1774 $desc_id = !empty($field['field_description']) ? $field_id . '-desc' : '';
1775 $aria_desc = !empty($desc_id) ? ' aria-describedby="' . esc_attr($desc_id) . '"' : '';
1776 $value_id = $field_id . '-value';
1777
1778 $html = '<div class="king-pricing-calculator__range-field">';
1779 $html .= '<input type="range" id="' . esc_attr($field_id) . '" name="' . esc_attr($field_id) . '"';
1780 $html .= ' min="' . esc_attr($field['field_min']) . '" max="' . esc_attr($field['field_max']) . '" step="' . esc_attr($field['field_step']) . '"';
1781 $html .= ' value="' . esc_attr($field['field_default']) . '"';
1782 $html .= ' class="king-pricing-calculator__range"' . $aria_desc . ' aria-valuetext="' . esc_attr($field['field_default']) . (!empty($field['field_unit']) ? ' ' . $field['field_unit'] : '') . '">';
1783
1784 $html .= '<div class="king-pricing-calculator__range-value-display" aria-hidden="true">';
1785 $html .= '<span class="king-pricing-calculator__range-value" id="' . esc_attr($value_id) . '">' . esc_html($field['field_default']) . '</span>';
1786
1787 if (!empty($field['field_unit'])) {
1788 $html .= ' <span class="king-pricing-calculator__field-unit">' . esc_html($field['field_unit']) . '</span>';
1789 }
1790
1791 $html .= '</div>';
1792 $html .= '</div>';
1793
1794 return $html;
1795 }
1796
1797 /**
1798 * Render a select dropdown field
1799 *
1800 * @param array $field Field settings
1801 * @param string $field_id Unique field ID
1802 * @return string HTML markup for select field
1803 */
1804 protected function render_select_field($field, $field_id)
1805 {
1806 $options = $this->parse_options($field['field_options']);
1807 $desc_id = !empty($field['field_description']) ? $field_id . '-desc' : '';
1808 $aria_desc = !empty($desc_id) ? ' aria-describedby="' . esc_attr($desc_id) . '"' : '';
1809
1810 $html = '<select id="' . esc_attr($field_id) . '" name="' . esc_attr($field_id) . '" class="king-pricing-calculator__select"' . $aria_desc . '>';
1811
1812 foreach ($options as $option) {
1813 $html .= '<option value="' . esc_attr($option['value']) . '" data-price="' . esc_attr($option['price']) . '">' . esc_html($option['label']) . '</option>';
1814 }
1815
1816 $html .= '</select>';
1817
1818 return $html;
1819 }
1820
1821 /**
1822 * Render radio button options
1823 *
1824 * @param array $field Field settings
1825 * @param string $field_id Unique field ID
1826 * @return string HTML markup for radio buttons
1827 */
1828 protected function render_radio_field($field, $field_id)
1829 {
1830 $options = $this->parse_options($field['field_options']);
1831 $desc_id = !empty($field['field_description']) ? $field_id . '-desc' : '';
1832 $fieldset_id = $field_id . '-group';
1833
1834 $html = '<fieldset id="' . esc_attr($fieldset_id) . '" class="king-pricing-calculator__radio-group">';
1835 if (!empty($desc_id)) {
1836 $html .= '<div aria-describedby="' . esc_attr($desc_id) . '" hidden></div>';
1837 }
1838
1839 foreach ($options as $index => $option) {
1840 $option_id = $field_id . '_' . $index;
1841
1842 $html .= '<div class="king-pricing-calculator__radio-option">';
1843 $html .= '<input type="radio" id="' . esc_attr($option_id) . '" name="' . esc_attr($field_id) . '"';
1844 $html .= ' value="' . esc_attr($option['value']) . '" data-price="' . esc_attr($option['price']) . '"';
1845
1846 if ($index === 0) {
1847 $html .= ' checked';
1848 }
1849
1850 $html .= ' class="king-pricing-calculator__radio">';
1851 $html .= '<label for="' . esc_attr($option_id) . '">' . esc_html($option['label']) . '</label>';
1852 $html .= '</div>';
1853 }
1854
1855 $html .= '</fieldset>';
1856
1857 return $html;
1858 }
1859
1860 /**
1861 * Render a checkbox field
1862 *
1863 * @param array $field Field settings
1864 * @param string $field_id Unique field ID
1865 * @return string HTML markup for checkbox
1866 */
1867 protected function render_checkbox_field($field, $field_id)
1868 {
1869 $desc_id = !empty($field['field_description']) ? $field_id . '-desc' : '';
1870 $aria_desc = !empty($desc_id) ? ' aria-describedby="' . esc_attr($desc_id) . '"' : '';
1871
1872 $html = '<div class="king-pricing-calculator__checkbox-field">';
1873 $html .= '<input type="checkbox" id="' . esc_attr($field_id) . '" name="' . esc_attr($field_id) . '"';
1874 $html .= ' class="king-pricing-calculator__checkbox"' . $aria_desc . '>';
1875 $html .= '</div>';
1876
1877 return $html;
1878 }
1879
1880 /**
1881 * Render a toggle switch field
1882 *
1883 * @param array $field Field settings
1884 * @param string $field_id Unique field ID
1885 * @return string HTML markup for switch
1886 */
1887 protected function render_switch_field($field, $field_id)
1888 {
1889 $desc_id = !empty($field['field_description']) ? $field_id . '-desc' : '';
1890 $aria_desc = !empty($desc_id) ? ' aria-describedby="' . esc_attr($desc_id) . '"' : '';
1891
1892 $html = '<label class="king-pricing-calculator__switch">';
1893 $html .= '<input type="checkbox" id="' . esc_attr($field_id) . '" name="' . esc_attr($field_id) . '"';
1894 $html .= ' class="king-pricing-calculator__switch-input"' . $aria_desc . ' role="switch">';
1895 $html .= '<span class="king-pricing-calculator__switch-slider" aria-hidden="true"></span>';
1896 $html .= '</label>';
1897
1898 return $html;
1899 }
1900
1901 /**
1902 * Parse options string into structured array
1903 *
1904 * @param string $options_string Options in format "value|label|price"
1905 * @return array Structured options array
1906 */
1907 protected function parse_options($options_string)
1908 {
1909 $options = [];
1910 $lines = explode("\n", $options_string);
1911
1912 foreach ($lines as $line) {
1913 $parts = explode('|', trim($line));
1914
1915 if (count($parts) >= 3) {
1916 $options[] = [
1917 'value' => $parts[0],
1918 'label' => $parts[1],
1919 'price' => floatval($parts[2]),
1920 ];
1921 }
1922 }
1923
1924 return $options;
1925 }
1926
1927 /**
1928 * Render widget output on the frontend
1929 */
1930 protected function render()
1931 {
1932 $settings = $this->get_settings_for_display();
1933 $id_int = substr($this->get_id_int(), 0, 3);
1934
1935 $calculator_id = 'king-pricing-calculator-' . $this->get_id();
1936 $calculator_classes = ['king-pricing-calculator'];
1937
1938 if ($settings['live_calculation'] === 'yes') {
1939 $calculator_classes[] = 'king-pricing-calculator--live';
1940 }
1941
1942 $calculator_classes = $this->filter_calculator_classes($calculator_classes, $settings);
1943
1944 $attributes = [
1945 'id' => $calculator_id,
1946 'class' => $calculator_classes,
1947 'data-base-price' => floatval($settings['base_price']),
1948 'data-decimal-places' => intval($settings['decimal_places']),
1949 'data-thousand-separator' => esc_attr($settings['thousand_separator']),
1950 'data-decimal-separator' => esc_attr($settings['decimal_separator']),
1951 'data-price-prefix' => esc_attr($settings['price_prefix']),
1952 'data-price-suffix' => esc_attr($settings['price_suffix']),
1953 ];
1954
1955 $attributes = $this->filter_calculator_attributes($attributes, $settings);
1956
1957 $this->add_render_attribute('calculator', $attributes);
1958
1959 ?>
1960 <div <?php $this->print_render_attribute_string('calculator'); ?>>
1961 <?php if (!empty($settings['calculator_title'])) : ?>
1962 <h2 class="king-pricing-calculator__title"><?php echo esc_html($settings['calculator_title']); ?></h2>
1963 <?php endif; ?>
1964
1965 <?php if (!empty($settings['calculator_description'])) : ?>
1966 <div class="king-pricing-calculator__description"><?php echo esc_html($settings['calculator_description']); ?></div>
1967 <?php endif; ?>
1968
1969 <div class="king-pricing-calculator__fields">
1970 <?php
1971 if (!empty($settings['calculator_fields'])) {
1972 foreach ($settings['calculator_fields'] as $index => $field) {
1973 // Use custom field ID if provided, otherwise generate an automatic one
1974 if (!empty($field['field_id'])) {
1975 $field_id = 'king-calc-' . sanitize_key($field['field_id']);
1976 } else {
1977 $field_id = 'king-calculator-field-' . $id_int . '-' . $index;
1978 }
1979 echo $this->render_field($field, $field_id);
1980 }
1981 }
1982 ?>
1983 </div>
1984
1985 <?php if ($settings['enable_calculate_button'] === 'yes' && $settings['live_calculation'] !== 'yes') : ?>
1986 <div class="king-pricing-calculator__calculate-button-wrapper">
1987 <button type="button" class="king-pricing-calculator__calculate-button">
1988 <?php echo esc_html($settings['calculate_button_text']); ?>
1989 </button>
1990 </div>
1991 <?php endif; ?>
1992
1993 <?php if ($settings['show_summary'] === 'yes') : ?>
1994 <div class="king-pricing-calculator__summary">
1995 <?php if (!empty($settings['summary_title'])) : ?>
1996 <h3 class="king-pricing-calculator__summary-title"><?php echo esc_html($settings['summary_title']); ?></h3>
1997 <?php endif; ?>
1998
1999 <div class="king-pricing-calculator__summary-items"></div>
2000 </div>
2001 <?php endif; ?>
2002
2003 <div class="king-pricing-calculator__total">
2004 <div class="king-pricing-calculator__total-content">
2005 <span class="king-pricing-calculator__total-label"><?php echo esc_html($settings['total_text']); ?></span>
2006 <span class="king-pricing-calculator__total-price">
2007 <?php echo esc_html($settings['price_prefix'] . $this->format_number($settings['base_price'], $settings) . $settings['price_suffix']); ?>
2008 </span>
2009 </div>
2010 </div>
2011
2012 <?php if (!king_addons_freemius()->can_use_premium_code__premium_only()) : ?>
2013 <div class="king-pricing-calculator__pro-features">
2014 <a href="https://kingaddons.com/pricing/?utm_source=kng-module-pricing-calculator-widget-upgrade-pro&utm_medium=plugin&utm_campaign=kng" target="_blank">
2015 <?php echo esc_html__('Notice for Editors: Upgrade to Pro for advanced pricing formulas, conditional logic & more features', 'king-addons'); ?>
2016 </a>
2017 </div>
2018 <?php endif; ?>
2019 </div>
2020 <?php $this->render_pro_after($settings); ?>
2021 <?php
2022 }
2023 }