PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.84
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.84
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 / 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.84, at includes/widgets/Pricing_Calculator/Pricing_Calculator.php

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