diff --git a/Gruntfile.js b/Gruntfile.js
index cf9b2285a..6236889cc 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -28,7 +28,8 @@ module.exports = function( grunt) {
// one to one
front: {
files: {
- '<%= dirs.css %>/frontend-forms.css': '<%= dirs.less %>/frontend-forms.less'
+ '<%= dirs.css %>/frontend-forms.css': '<%= dirs.less %>/frontend-forms.less',
+ '<%= dirs.css %>/elementor-frontend-forms.css': '<%= dirs.less %>/elementor-frontend-forms.less'
}
},
diff --git a/assets/css/elementor-frontend-forms.css b/assets/css/elementor-frontend-forms.css
new file mode 100644
index 000000000..c46f8e910
--- /dev/null
+++ b/assets/css/elementor-frontend-forms.css
@@ -0,0 +1,197 @@
+/**
+ * DESCRIPTION: Elementor-specific WPUF frontend form styles
+ *
+ * This file contains form styles scoped to the Elementor widget wrapper
+ * to avoid conflicts with the theme and provide better Elementor integration.
+ *
+ * @package WPUF\Elementor
+ */
+.wpuf-elementor-widget-wrapper {
+ --wpuf-border-color: #dadbdd;
+ --wpuf-border-radius: 7px;
+ --wpuf-text-color: #606266;
+ --wpuf-primary-color: #1a7efb;
+ --wpuf-danger-color: #F56C6C;
+}
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="text"],
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="email"],
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="url"],
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="password"],
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="number"],
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="tel"],
+.wpuf-elementor-widget-wrapper .wpuf-fields textarea,
+.wpuf-elementor-widget-wrapper .wpuf-fields select {
+ padding: 12px 15px;
+ color: var(--wpuf-text-color);
+ border: 1px solid var(--wpuf-border-color);
+ border-radius: var(--wpuf-border-radius);
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ margin-bottom: 0;
+ width: 100%;
+}
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="text"]:focus,
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="email"]:focus,
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="url"]:focus,
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="password"]:focus,
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="number"]:focus,
+.wpuf-elementor-widget-wrapper .wpuf-fields input[type="tel"]:focus,
+.wpuf-elementor-widget-wrapper .wpuf-fields textarea:focus,
+.wpuf-elementor-widget-wrapper .wpuf-fields select:focus {
+ color: var(--wpuf-text-color);
+ background-color: #fff;
+ border-color: var(--wpuf-primary-color);
+ outline: none;
+ box-shadow: 0 0 0 2px rgba(26, 126, 251, 0.1);
+}
+.wpuf-elementor-widget-wrapper .wpuf-fields .wpuf-radio-block,
+.wpuf-elementor-widget-wrapper .wpuf-fields .wpuf-checkbox-block {
+ display: flex;
+ align-items: center;
+ margin-bottom: 6px;
+}
+.wpuf-elementor-widget-wrapper ul.wpuf-form {
+ list-style: none;
+}
+.wpuf-elementor-widget-wrapper ul.wpuf-form li:not(:first-child) {
+ margin-top: 2rem;
+}
+.wpuf-elementor-widget-wrapper ul.wpuf-form li.wpuf-el .wpuf-label {
+ margin-bottom: 1rem;
+}
+.wpuf-elementor-widget-wrapper[data-align="left"] {
+ margin: 0 auto 0 0;
+}
+.wpuf-elementor-widget-wrapper[data-align="center"] {
+ margin: 0 auto;
+}
+.wpuf-elementor-widget-wrapper[data-align="right"] {
+ margin: 0 0 0 auto;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-submit-full .wpuf-submit .wpuf-submit-button {
+ width: 100%;
+ display: block;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-upload-full .wpuf-attachment-upload-filelist .file-selector {
+ width: 100%;
+ display: block;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-labels .wpuf-label {
+ display: none !important;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-errors .wpuf-error,
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-errors .error {
+ display: none;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder input::-webkit-input-placeholder,
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder textarea::-webkit-input-placeholder {
+ opacity: 0;
+ visibility: hidden;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder input::-moz-placeholder,
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder textarea::-moz-placeholder {
+ opacity: 0;
+ visibility: hidden;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder input:-moz-placeholder,
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder textarea:-moz-placeholder {
+ opacity: 0;
+ visibility: hidden;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder input:-ms-input-placeholder,
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder textarea:-ms-input-placeholder {
+ opacity: 0;
+ visibility: hidden;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder input::-ms-input-placeholder,
+.wpuf-elementor-widget-wrapper.wpuf-elementor-hide-placeholder textarea::-ms-input-placeholder {
+ opacity: 0;
+ visibility: hidden;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-custom-radio-checkbox input[type="checkbox"],
+.wpuf-elementor-widget-wrapper.wpuf-elementor-custom-radio-checkbox input[type="radio"] {
+ outline: none;
+ min-width: 1px;
+ width: 15px;
+ height: 15px;
+ background: #ddd;
+ padding: 3px;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-custom-radio-checkbox input[type="radio"] {
+ border-radius: 50%;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-submit-center .wpuf-submit {
+ text-align: center;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-submit-center .wpuf-submit .wpuf-submit-button {
+ margin: 0 auto;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-submit-right .wpuf-submit {
+ text-align: right;
+}
+.wpuf-elementor-widget-wrapper.wpuf-elementor-submit-left .wpuf-submit {
+ text-align: left;
+}
+.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ flex-wrap: wrap;
+}
+.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .refresh {
+ cursor: pointer;
+ transition: opacity 0.2s ease;
+}
+.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .refresh:hover {
+ opacity: 0.7;
+}
+.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .refresh svg {
+ display: block;
+}
+.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .captcha-number-area .captcha-number {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ margin: 0;
+ font-size: 16px;
+ font-weight: 500;
+ color: var(--wpuf-text-color);
+}
+.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .captcha-equal {
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--wpuf-text-color);
+}
+.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .wpuf-captcha-input-wrapper {
+ flex: 1;
+ min-width: 80px;
+ position: relative;
+}
+.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .wpuf-captcha-input-wrapper .wpuf-captcha-input {
+ padding: 11px 15px;
+ color: var(--wpuf-text-color);
+ border: 1px solid var(--wpuf-border-color);
+ border-radius: var(--wpuf-border-radius);
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ margin-bottom: 0;
+ width: 100%;
+ font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
+}
+.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .wpuf-captcha-input-wrapper .wpuf-captcha-input:focus {
+ color: var(--wpuf-text-color);
+ background-color: #fff;
+ border-color: var(--wpuf-primary-color);
+ outline: none;
+ box-shadow: 0 0 0 2px rgba(26, 126, 251, 0.1);
+}
+.wpuf-elementor-widget-wrapper .wpuf-math-captcha .captcha .wpuf-captcha-input-wrapper .wpuf-captcha-error {
+ display: block;
+ margin-top: 5px;
+ font-size: 13px;
+ color: var(--wpuf-danger-color);
+}
+.lity {
+ z-index: 9999 !important;
+}
diff --git a/assets/css/elementor-subscription-plans.css b/assets/css/elementor-subscription-plans.css
new file mode 100644
index 000000000..53d3c8301
--- /dev/null
+++ b/assets/css/elementor-subscription-plans.css
@@ -0,0 +1,195 @@
+/**
+ * DESCRIPTION: Elementor-specific WPUF subscription plans styles
+ *
+ * This file contains subscription plans display styles scoped to the
+ * Elementor widget wrapper to avoid conflicts with the theme.
+ * Design values (colors, fonts, spacing) are controlled by Elementor widget settings.
+ *
+ * @package WPUF\Elementor
+ */
+
+/* Widget Container */
+.wpuf-subscription-plans-wrapper {
+ width: 100%;
+ margin: 0 auto;
+}
+
+/* Grid Layout */
+.wpuf-subscription-plans-grid {
+ display: grid;
+}
+
+/* Responsive: Mobile - 1 column */
+@media (max-width: 767px) {
+ .wpuf-subscription-plans-grid {
+ grid-template-columns: 1fr;
+ }
+}
+
+/* Plans Per Row: 1 column */
+.wpuf-subscription-plans-wrapper.wpuf-sub-plans-1 .wpuf-subscription-plans-grid {
+ grid-template-columns: 1fr;
+}
+
+/* Plans Per Row: 2 columns */
+@media (min-width: 768px) {
+ .wpuf-subscription-plans-wrapper.wpuf-sub-plans-2 .wpuf-subscription-plans-grid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
+
+/* Plans Per Row: 3 columns */
+@media (min-width: 768px) {
+ .wpuf-subscription-plans-wrapper.wpuf-sub-plans-3 .wpuf-subscription-plans-grid {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
+
+/* Plans Per Row: 4 columns */
+@media (min-width: 768px) {
+ .wpuf-subscription-plans-wrapper.wpuf-sub-plans-4 .wpuf-subscription-plans-grid {
+ grid-template-columns: repeat(4, 1fr);
+ }
+}
+
+/* Plan Card */
+.wpuf-sub-card {
+ transition: box-shadow 0.3s ease, transform 0.3s ease;
+}
+
+.wpuf-sub-card:hover {
+ box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
+}
+
+/* Plan Name */
+.wpuf-sub-plan-name {
+ margin: 0 0 0 0;
+ line-height: 1.3;
+}
+
+/* Description */
+.wpuf-sub-description {
+ margin-bottom: 20px;
+ line-height: 1.6;
+}
+
+.wpuf-sub-description p {
+ margin: 0 0 12px 0;
+}
+
+.wpuf-sub-description p:last-child {
+ margin-bottom: 0;
+}
+
+/* Price Wrapper */
+.wpuf-sub-price-wrapper {
+ margin-bottom: 20px;
+}
+
+/* Price */
+.wpuf-sub-price {
+ display: flex;
+ align-items: baseline;
+ flex-wrap: wrap;
+ gap: 4px;
+ line-height: 1.2;
+}
+
+/* Trial Description */
+.wpuf-sub-trial-description {
+ margin-bottom: 20px;
+ line-height: 1.5;
+}
+
+/* Button Wrapper */
+.wpuf-sub-button-wrapper {
+ margin-bottom: 20px;
+}
+
+/* Subscribe Button */
+.wpuf-sub-button {
+ display: inline-block;
+ text-align: center;
+ text-decoration: none;
+ transition: all 0.2s ease;
+ cursor: pointer;
+}
+
+.wpuf-sub-button:hover {
+ opacity: 0.9;
+}
+
+.wpuf-sub-button-disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+ pointer-events: none;
+}
+
+/* Features List */
+.wpuf-sub-features-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.wpuf-sub-feature-item {
+ display: flex;
+ align-items: flex-start;
+ gap: 12px;
+ line-height: 1.5;
+}
+
+.wpuf-sub-feature-item:last-child {
+ margin-bottom: 0;
+}
+
+.wpuf-sub-feature-icon {
+ flex-shrink: 0;
+ margin-top: 2px;
+}
+
+.wpuf-sub-feature-hidden {
+ display: none;
+}
+
+/* Features Toggle Button */
+.wpuf-sub-features-toggle-wrapper {
+ margin-top: 16px;
+}
+
+.wpuf-sub-features-toggle {
+ background: none;
+ border: none;
+ padding: 0;
+ cursor: pointer;
+ text-decoration: none;
+ transition: opacity 0.2s ease;
+}
+
+.wpuf-sub-features-toggle:hover {
+ opacity: 0.8;
+}
+
+/* Empty State (Editor) */
+.wpuf-subscription-empty-state {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 60px 20px;
+ text-align: center;
+ border: 2px dashed #d1d5db;
+ border-radius: 12px;
+}
+
+.wpuf-subscription-empty-icon {
+ margin-bottom: 16px;
+}
+
+.wpuf-subscription-empty-text {
+ margin: 0 0 8px 0;
+}
+
+.wpuf-subscription-empty-hint {
+ margin: 0;
+}
diff --git a/assets/js/elementor-subscription-plans.js b/assets/js/elementor-subscription-plans.js
new file mode 100644
index 000000000..32042b79c
--- /dev/null
+++ b/assets/js/elementor-subscription-plans.js
@@ -0,0 +1,44 @@
+/**
+ * DESCRIPTION: Elementor subscription plans widget JavaScript
+ *
+ * Handles the expandable features list functionality for the
+ * subscription plans widget.
+ *
+ * @package WPUF\Elementor
+ */
+
+(function() {
+ 'use strict';
+
+ // Handle feature toggle buttons
+ document.addEventListener('click', function(e) {
+ if (e.target.classList.contains('wpuf-sub-features-toggle')) {
+ e.preventDefault();
+ var button = e.target;
+ var packId = button.getAttribute('data-pack-id');
+ var isExpanded = button.getAttribute('data-expanded') === 'true';
+ var featuresList = document.getElementById('wpuf-sub-features-list-' + packId);
+ var seeMoreBtn = featuresList.parentElement.querySelector('.wpuf-sub-features-see-more');
+ var seeLessBtn = featuresList.parentElement.querySelector('.wpuf-sub-features-see-less');
+ var hiddenItems = featuresList.querySelectorAll('.wpuf-sub-feature-hidden');
+
+ if (isExpanded) {
+ // Collapse
+ hiddenItems.forEach(function(item) {
+ item.style.display = 'none';
+ });
+ seeMoreBtn.style.display = '';
+ seeLessBtn.style.display = 'none';
+ button.setAttribute('data-expanded', 'false');
+ } else {
+ // Expand
+ hiddenItems.forEach(function(item) {
+ item.style.display = 'flex';
+ });
+ seeMoreBtn.style.display = 'none';
+ seeLessBtn.style.display = '';
+ seeLessBtn.setAttribute('data-expanded', 'true');
+ }
+ }
+ });
+})();
diff --git a/assets/less/elementor-frontend-forms.less b/assets/less/elementor-frontend-forms.less
new file mode 100644
index 000000000..553e0973c
--- /dev/null
+++ b/assets/less/elementor-frontend-forms.less
@@ -0,0 +1,254 @@
+/**
+ * DESCRIPTION: Elementor-specific WPUF frontend form styles
+ *
+ * This file contains form styles scoped to the Elementor widget wrapper
+ * to avoid conflicts with the theme and provide better Elementor integration.
+ *
+ * @package WPUF\Elementor
+ */
+
+// ============================================
+// CSS Custom Properties (Variables)
+// ============================================
+
+.wpuf-elementor-widget-wrapper {
+ --wpuf-border-color: #dadbdd;
+ --wpuf-border-radius: 7px;
+ --wpuf-text-color: #606266;
+ --wpuf-primary-color: #1a7efb;
+ --wpuf-danger-color: #F56C6C;
+
+ // ============================================
+ // Base Input Styles
+ // ============================================
+
+ .wpuf-fields input[type="text"],
+ .wpuf-fields input[type="email"],
+ .wpuf-fields input[type="url"],
+ .wpuf-fields input[type="password"],
+ .wpuf-fields input[type="number"],
+ .wpuf-fields input[type="tel"],
+ .wpuf-fields textarea,
+ .wpuf-fields select {
+ padding: 12px 15px;
+ color: var(--wpuf-text-color);
+ border: 1px solid var(--wpuf-border-color);
+ border-radius: var(--wpuf-border-radius);
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ margin-bottom: 0;
+ width: 100%;
+
+ &:focus {
+ color: var(--wpuf-text-color);
+ background-color: #fff;
+ border-color: var(--wpuf-primary-color);
+ outline: none;
+ box-shadow: 0 0 0 2px rgba(26, 126, 251, 0.1);
+ }
+ }
+
+ .wpuf-fields .wpuf-radio-block,
+ .wpuf-fields .wpuf-checkbox-block {
+ display: flex;
+ align-items: center;
+ margin-bottom: 6px;
+ }
+
+ ul.wpuf-form {
+ list-style: none;
+
+ li:not(:first-child) {
+ margin-top: 2rem;
+ }
+
+ li.wpuf-el {
+ .wpuf-label {
+ margin-bottom: 1rem;
+ }
+
+ }
+ }
+
+ // Container alignment based on data-align attribute
+ &[data-align="left"] {
+ margin: 0 auto 0 0;
+ }
+
+ &[data-align="center"] {
+ margin: 0 auto;
+ }
+
+ &[data-align="right"] {
+ margin: 0 0 0 auto;
+ }
+
+ // Full width submit button
+ &.wpuf-elementor-submit-full .wpuf-submit .wpuf-submit-button {
+ width: 100%;
+ display: block;
+ }
+
+ // Full width upload button
+ &.wpuf-elementor-upload-full .wpuf-attachment-upload-filelist .file-selector {
+ width: 100%;
+ display: block;
+ }
+
+ // Hide labels option
+ &.wpuf-elementor-hide-labels .wpuf-label {
+ display: none !important;
+ }
+
+ // Hide error messages option
+ &.wpuf-elementor-hide-errors .wpuf-error,
+ &.wpuf-elementor-hide-errors .error {
+ display: none;
+ }
+
+ // Hide placeholder option
+ &.wpuf-elementor-hide-placeholder input::-webkit-input-placeholder,
+ &.wpuf-elementor-hide-placeholder textarea::-webkit-input-placeholder {
+ opacity: 0;
+ visibility: hidden;
+ }
+
+ &.wpuf-elementor-hide-placeholder input::-moz-placeholder,
+ &.wpuf-elementor-hide-placeholder textarea::-moz-placeholder {
+ opacity: 0;
+ visibility: hidden;
+ }
+
+ &.wpuf-elementor-hide-placeholder input:-moz-placeholder,
+ &.wpuf-elementor-hide-placeholder textarea:-moz-placeholder {
+ opacity: 0;
+ visibility: hidden;
+ }
+
+ &.wpuf-elementor-hide-placeholder input:-ms-input-placeholder,
+ &.wpuf-elementor-hide-placeholder textarea:-ms-input-placeholder {
+ opacity: 0;
+ visibility: hidden;
+ }
+
+ &.wpuf-elementor-hide-placeholder input::-ms-input-placeholder,
+ &.wpuf-elementor-hide-placeholder textarea::-ms-input-placeholder {
+ opacity: 0;
+ visibility: hidden;
+ }
+
+ // Custom radio/checkbox styling
+ &.wpuf-elementor-custom-radio-checkbox input[type="checkbox"],
+ &.wpuf-elementor-custom-radio-checkbox input[type="radio"] {
+ outline: none;
+ min-width: 1px;
+ width: 15px;
+ height: 15px;
+ background: #ddd;
+ padding: 3px;
+ }
+
+ &.wpuf-elementor-custom-radio-checkbox input[type="radio"] {
+ border-radius: 50%;
+ }
+
+ // Submit button alignment
+ &.wpuf-elementor-submit-center .wpuf-submit {
+ text-align: center;
+
+ .wpuf-submit-button {
+ margin: 0 auto;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ }
+ }
+
+ &.wpuf-elementor-submit-right .wpuf-submit {
+ text-align: right;
+ }
+
+ &.wpuf-elementor-submit-left .wpuf-submit {
+ text-align: left;
+ }
+
+ // ============================================
+ // Math Captcha Styles
+ // ============================================
+
+ .wpuf-math-captcha {
+ .captcha {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ flex-wrap: wrap;
+
+ .refresh {
+ cursor: pointer;
+ transition: opacity 0.2s ease;
+
+ &:hover {
+ opacity: 0.7;
+ }
+
+ svg {
+ display: block;
+ }
+ }
+
+ .captcha-number-area {
+ .captcha-number {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ margin: 0;
+ font-size: 16px;
+ font-weight: 500;
+ color: var(--wpuf-text-color);
+ }
+ }
+
+ .captcha-equal {
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--wpuf-text-color);
+ }
+
+ .wpuf-captcha-input-wrapper {
+ flex: 1;
+ min-width: 80px;
+ position: relative;
+
+ .wpuf-captcha-input {
+ padding: 11px 15px;
+ color: var(--wpuf-text-color);
+ border: 1px solid var(--wpuf-border-color);
+ border-radius: var(--wpuf-border-radius);
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ margin-bottom: 0;
+ width: 100%;
+ font-family: -apple-system, system-ui, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
+
+ &:focus {
+ color: var(--wpuf-text-color);
+ background-color: #fff;
+ border-color: var(--wpuf-primary-color);
+ outline: none;
+ box-shadow: 0 0 0 2px rgba(26, 126, 251, 0.1);
+ }
+ }
+
+ .wpuf-captcha-error {
+ display: block;
+ margin-top: 5px;
+ font-size: 13px;
+ color: var(--wpuf-danger-color);
+ }
+ }
+ }
+ }
+}
+
+// Ensure lity popup appears above Elementor popup
+.lity {
+ z-index: 9999 !important;
+}
\ No newline at end of file
diff --git a/includes/Admin/template-parts/modal-v4.2.php b/includes/Admin/template-parts/modal-v4.2.php
index 94e668198..dab721df6 100644
--- a/includes/Admin/template-parts/modal-v4.2.php
+++ b/includes/Admin/template-parts/modal-v4.2.php
@@ -454,8 +454,6 @@ class="wpuf-btn-secondary wpuf-w-max wpuf-absolute wpuf-top-[50%] wpuf-left-[50%
$( '.wpuf-ai-forms-template a' ).on( 'click', $.proxy( this.handleAIFormsClick, this ) );
$( '#ai-config-cancel' ).on( 'click', $.proxy( this.closeAIConfigModal, this ) );
$( '#ai-config-settings' ).on( 'click', $.proxy( this.goToSettings, this ) );
- } else {
- console.log('NOT attaching AI click handler - AI is configured or template not found');
}
},
diff --git a/includes/Assets.php b/includes/Assets.php
index aa9a20372..f28e1005b 100644
--- a/includes/Assets.php
+++ b/includes/Assets.php
@@ -109,6 +109,12 @@ public function get_styles() {
'frontend-forms' => [
'src' => WPUF_ASSET_URI . '/css/frontend-forms.css',
],
+ 'elementor-frontend-forms' => [
+ 'src' => WPUF_ASSET_URI . '/css/elementor-frontend-forms.css',
+ ],
+ 'elementor-subscription-plans' => [
+ 'src' => WPUF_ASSET_URI . '/css/elementor-subscription-plans.css',
+ ],
'frontend-subscriptions' => [
'src' => WPUF_ASSET_URI . '/css/frontend-subscriptions.min.css',
],
@@ -415,6 +421,10 @@ public function get_scripts() {
'src' => WPUF_ASSET_URI . '/js/frontend-subscriptions.min.js',
'in_footer' => true,
],
+ 'elementor-subscription-plans' => [
+ 'src' => WPUF_ASSET_URI . '/js/elementor-subscription-plans.js',
+ 'in_footer' => true,
+ ],
];
if ( ! empty( $api_key ) ) {
diff --git a/includes/Fields/Field_Contract.php b/includes/Fields/Field_Contract.php
index cd714f454..7535fb11c 100755
--- a/includes/Fields/Field_Contract.php
+++ b/includes/Fields/Field_Contract.php
@@ -763,6 +763,33 @@ public function get_default_textarea_option_settings() {
];
}
+ /**
+ * Check if we should render admin-style markup
+ *
+ * Returns true for admin dashboard, but false for Elementor editor
+ * since Elementor editor needs frontend-style markup for proper preview.
+ *
+ * @since WPUF_SINCE
+ *
+ * @return bool
+ */
+ protected function use_admin_markup() {
+ if ( ! is_admin() ) {
+ return false;
+ }
+
+ // Check if we're in Elementor editor mode
+ // Elementor editor needs frontend markup for proper preview
+ if ( class_exists( '\Elementor\Plugin' ) ) {
+ $elementor = \Elementor\Plugin::$instance;
+ if ( $elementor && $elementor->editor && $elementor->editor->is_edit_mode() ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
/**
* Prints form input label for admin
*
@@ -770,7 +797,7 @@ public function get_default_textarea_option_settings() {
* @param int $form_id
*/
public function field_print_label( $field, $form_id = 0 ) {
- if ( is_admin() ) { ?>
+ if ( $this->use_admin_markup() ) { ?>
print_list_attributes( $field ); ?>> | required_mark( $field ) ); ?> |
@@ -782,7 +809,7 @@ public function field_print_label( $field, $form_id = 0 ) {
}
public function after_field_print_label() {
- if ( is_admin() ) {
+ if ( $this->use_admin_markup() ) {
?>
|
diff --git a/includes/Fields/Form_Field_Post_Excerpt.php b/includes/Fields/Form_Field_Post_Excerpt.php
index b3d8c9aae..636853bc9 100755
--- a/includes/Fields/Form_Field_Post_Excerpt.php
+++ b/includes/Fields/Form_Field_Post_Excerpt.php
@@ -56,6 +56,7 @@ public function render( $field_settings, $form_id, $type = 'post', $post_id = nu
];
$editor_settings = apply_filters( 'wpuf_textarea_editor_args', $editor_settings );
+
wp_editor( $value, $textarea_id, $editor_settings );
} elseif ( ! empty( $field_settings['rich'] ) && $field_settings['rich'] == 'teeny' ) {
$editor_settings = [
@@ -68,6 +69,7 @@ public function render( $field_settings, $form_id, $type = 'post', $post_id = nu
];
$editor_settings = apply_filters( 'wpuf_textarea_editor_args', $editor_settings );
+
wp_editor( $value, $textarea_id, $editor_settings );
} else {
?>
diff --git a/includes/Frontend.php b/includes/Frontend.php
index 908332727..9785e13bf 100644
--- a/includes/Frontend.php
+++ b/includes/Frontend.php
@@ -68,8 +68,11 @@ public function enqueue_scripts() {
// Load appropriate subscription script based on shortcode
if ( wpuf_has_shortcode( 'wpuf_sub_pack' ) ) {
- // Load new frontend-subscriptions script for subscription pack shortcode (pricing page)
- wp_enqueue_style( 'wpuf-frontend-subscriptions' );
+ // Skip loading frontend-subscriptions CSS on Elementor pages (Elementor widget has its own CSS)
+ $is_elementor_page = did_action( 'elementor/loaded' ) && isset( $post->ID ) && \Elementor\Plugin::$instance->db->is_built_with_elementor( $post->ID );
+ if ( ! $is_elementor_page ) {
+ wp_enqueue_style( 'wpuf-frontend-subscriptions' );
+ }
wp_enqueue_script( 'wpuf-frontend-subscriptions' );
} else {
// Load old subscriptions script for all other pages (dashboard, account, etc.)
diff --git a/includes/Integrations.php b/includes/Integrations.php
index 99bb8ea77..eca318303 100644
--- a/includes/Integrations.php
+++ b/includes/Integrations.php
@@ -45,6 +45,10 @@ public function __construct() {
}
}
}
+
+ add_action('elementor/init', function() {
+ $this->container['elementor'] = new Integrations\Elementor\Elementor();
+ });
}
/**
diff --git a/includes/Integrations/Elementor/Elementor.php b/includes/Integrations/Elementor/Elementor.php
new file mode 100644
index 000000000..40e5e87af
--- /dev/null
+++ b/includes/Integrations/Elementor/Elementor.php
@@ -0,0 +1,261 @@
+enqueue_wpuf_form_assets();
+
+ // Ensure editor scripts are loaded for TinyMCE in Elementor preview
+ if ( function_exists( 'wp_enqueue_editor' ) ) {
+ wp_enqueue_editor();
+
+ // Also explicitly enqueue TinyMCE scripts if available
+ if ( function_exists( 'wp_enqueue_script' ) ) {
+ // Check if these scripts exist and enqueue them
+ global $wp_scripts;
+ if ( isset( $wp_scripts->registered['tinymce'] ) ) {
+ wp_enqueue_script( 'tinymce' );
+ }
+ if ( isset( $wp_scripts->registered['wp-tinymce'] ) ) {
+ wp_enqueue_script( 'wp-tinymce' );
+ }
+ }
+ }
+
+ /**
+ * Fires after WPUF has enqueued its scripts in Elementor context.
+ *
+ * @since WPUF_SINCE
+ */
+ do_action( 'wpuf_elementor_after_enqueue_scripts' );
+ }
+
+ /**
+ * Enqueue all required WPUF form assets for Elementor
+ *
+ * Ensures all necessary styles and scripts are loaded for WPUF forms
+ * to render properly in Elementor preview and frontend.
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ private function enqueue_wpuf_form_assets() {
+ // Core styles (already handled by enqueue_styles, but ensure they're available)
+ wp_enqueue_style( 'wpuf-sweetalert2' );
+ wp_enqueue_style( 'wpuf-jquery-ui' );
+
+ // Core scripts required for all WPUF forms
+ wp_enqueue_script( 'suggest' );
+ wp_enqueue_script( 'wpuf-billing-address' );
+ wp_enqueue_script( 'wpuf-upload' );
+ wp_enqueue_script( 'wpuf-frontend-form' );
+ wp_enqueue_script( 'wpuf-sweetalert2' );
+ wp_enqueue_script( 'wpuf-subscriptions' );
+
+ // Localize wpuf-upload script
+ wp_localize_script(
+ 'wpuf-upload',
+ 'wpuf_upload',
+ [
+ 'confirmMsg' => __( 'Are you sure?', 'wp-user-frontend' ),
+ 'delete_it' => __( 'Yes, delete it', 'wp-user-frontend' ),
+ 'cancel_it' => __( 'No, cancel it', 'wp-user-frontend' ),
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
+ 'nonce' => wp_create_nonce( 'wpuf_nonce' ),
+ 'plupload' => [
+ 'url' => admin_url( 'admin-ajax.php' ) . '?nonce=' . wp_create_nonce( 'wpuf-upload-nonce' ),
+ 'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ),
+ 'filters' => [
+ [
+ 'title' => __( 'Allowed Files', 'wp-user-frontend' ),
+ 'extensions' => '*',
+ ],
+ ],
+ 'multipart' => true,
+ 'urlstream_upload' => true,
+ 'warning' => __( 'Maximum number of files reached!', 'wp-user-frontend' ),
+ 'size_error' => __( 'The file you have uploaded exceeds the file size limit. Please try again.', 'wp-user-frontend' ),
+ 'type_error' => __( 'You have uploaded an incorrect file type. Please try again.', 'wp-user-frontend' ),
+ ],
+ ]
+ );
+
+ // Localize wpuf-frontend-form script
+ wp_localize_script(
+ 'wpuf-frontend-form',
+ 'wpuf_frontend',
+ apply_filters(
+ 'wpuf_frontend_object',
+ [
+ 'asset_url' => WPUF_ASSET_URI,
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
+ 'error_message' => __( 'Please fix the errors to proceed', 'wp-user-frontend' ),
+ 'nonce' => wp_create_nonce( 'wpuf_nonce' ),
+ 'word_limit' => __( 'Word limit reached', 'wp-user-frontend' ),
+ 'cancelSubMsg' => __( 'Are you sure you want to cancel your current subscription ?', 'wp-user-frontend' ),
+ 'delete_it' => __( 'Yes', 'wp-user-frontend' ),
+ 'cancel_it' => __( 'No', 'wp-user-frontend' ),
+ 'word_max_title' => __( 'Maximum word limit reached. Please shorten your texts.', 'wp-user-frontend' ),
+ 'word_max_details' => __( 'This field supports a maximum of %number% words, and the limit is reached. Remove a few words to reach the acceptable limit of the field.', 'wp-user-frontend' ),
+ 'word_min_title' => __( 'Minimum word required.', 'wp-user-frontend' ),
+ 'word_min_details' => __( 'This field requires minimum %number% words. Please add some more text.', 'wp-user-frontend' ),
+ 'char_max_title' => __( 'Maximum character limit reached. Please shorten your texts.', 'wp-user-frontend' ),
+ 'char_max_details' => __( 'This field supports a maximum of %number% characters, and the limit is reached. Remove a few characters to reach the acceptable limit of the field.', 'wp-user-frontend' ),
+ 'char_min_title' => __( 'Minimum character required.', 'wp-user-frontend' ),
+ 'char_min_details' => __( 'This field requires minimum %number% characters. Please add some more character.', 'wp-user-frontend' ),
+ 'protected_shortcodes' => wpuf_get_protected_shortcodes(),
+ 'protected_shortcodes_message' => __( 'Using %shortcode% is restricted', 'wp-user-frontend' ),
+ 'password_warning_weak' => __( 'Your password should be at least weak in strength', 'wp-user-frontend' ),
+ 'password_warning_medium' => __( 'Your password needs to be medium strength for better protection', 'wp-user-frontend' ),
+ 'password_warning_strong' => __( 'Create a strong password for maximum security', 'wp-user-frontend' ),
+ ]
+ )
+ );
+
+ wp_localize_script(
+ 'wpuf-frontend-form',
+ 'error_str_obj',
+ [
+ 'required' => __( 'is required', 'wp-user-frontend' ),
+ 'mismatch' => __( 'does not match', 'wp-user-frontend' ),
+ 'validation' => __( 'is not valid', 'wp-user-frontend' ),
+ ]
+ );
+
+ // Localize subscription script
+ wp_localize_script(
+ 'wpuf-subscriptions',
+ 'wpuf_subscription',
+ apply_filters(
+ 'wpuf_subscription_js_data',
+ [
+ 'pack_notice' => __( 'Please Cancel Your Currently Active Pack first!', 'wp-user-frontend' ),
+ ]
+ )
+ );
+
+ // Localize billing address script
+ wp_localize_script(
+ 'wpuf-billing-address',
+ 'ajax_object',
+ [
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
+ 'fill_notice' => __( 'Some Required Fields are not filled!', 'wp-user-frontend' ),
+ ]
+ );
+
+ // Conditionally enqueue Google Maps if API key is configured
+ $api_key = wpuf_get_option( 'gmap_api_key', 'wpuf_general' );
+ if ( ! empty( $api_key ) ) {
+ $scheme = is_ssl() ? 'https' : 'http';
+ wp_enqueue_script( 'wpuf-google-maps', $scheme . '://maps.google.com/maps/api/js?libraries=places&key=' . $api_key, [], null, true );
+ }
+ }
+
+ /**
+ * Register Elementor Widget Category
+ *
+ * @param \Elementor\Elements_Manager $elements_manager
+ *
+ * @return void
+ */
+ public function register_category( $elements_manager ) {
+ $elements_manager->add_category(
+ 'user-frontend',
+ [
+ 'title' => __( 'User Frontend', 'wp-user-frontend' ),
+ 'icon' => 'eicon-form-horizontal',
+ ]
+ );
+ }
+
+ /**
+ * Register Elementor Widgets
+ *
+ * @param \Elementor\Widgets_Manager $widgets_manager
+ *
+ * @return void
+ */
+ public function register_widgets( $widgets_manager ) {
+ require_once __DIR__ . '/Widget.php';
+ require_once __DIR__ . '/Subscription_Plans_Widget.php';
+
+ $widgets_manager->register( new Widget() );
+ $widgets_manager->register( new Subscription_Plans_Widget() );
+ }
+}
diff --git a/includes/Integrations/Elementor/Subscription_Plans_Widget.php b/includes/Integrations/Elementor/Subscription_Plans_Widget.php
new file mode 100644
index 000000000..1e5848bba
--- /dev/null
+++ b/includes/Integrations/Elementor/Subscription_Plans_Widget.php
@@ -0,0 +1,1506 @@
+register_content_controls();
+
+ // Style Controls
+ $this->register_container_style_controls();
+ $this->register_plan_name_style_controls();
+ $this->register_price_style_controls();
+ $this->register_trial_description_style_controls();
+ $this->register_features_list_style_controls();
+ $this->register_button_style_controls();
+ }
+
+ /**
+ * Register content controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_content_controls() {
+ $this->start_controls_section(
+ 'section_content',
+ [
+ 'label' => __( 'Content', 'wp-user-frontend' ),
+ ]
+ );
+
+ $this->add_control(
+ 'plans_per_row',
+ [
+ 'label' => __( 'Plans Per Row', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SELECT,
+ 'default' => '3',
+ 'options' => [
+ '1' => __( '1', 'wp-user-frontend' ),
+ '2' => __( '2', 'wp-user-frontend' ),
+ '3' => __( '3', 'wp-user-frontend' ),
+ '4' => __( '4', 'wp-user-frontend' ),
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'order_by',
+ [
+ 'label' => __( 'Order By', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SELECT,
+ 'default' => 'custom',
+ 'description' => __( 'Choose how to sort the subscription plans. Custom Order uses the sort order set in each plan\'s settings.', 'wp-user-frontend' ),
+ 'options' => [
+ 'custom' => __( 'Custom Order', 'wp-user-frontend' ),
+ 'id' => __( 'Plan ID', 'wp-user-frontend' ),
+ 'price_asc' => __( 'Price (Low to High)', 'wp-user-frontend' ),
+ 'price_desc' => __( 'Price (High to Low)', 'wp-user-frontend' ),
+ ],
+ ]
+ );
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register container style controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_container_style_controls() {
+ $this->start_controls_section(
+ 'section_container_style',
+ [
+ 'label' => __( 'Container', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'container_width',
+ [
+ 'label' => __( 'Container Width', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'range' => [
+ 'px' => [ 'min' => 100, 'max' => 1500 ],
+ '%' => [ 'min' => 10, 'max' => 100 ],
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-subscription-plans-wrapper' => 'max-width: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'container_bg_color',
+ [
+ 'label' => __( 'Background Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#ffffff',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-card' => 'background-color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Border::get_type(),
+ [
+ 'name' => 'card_border',
+ 'selector' => '{{WRAPPER}} .wpuf-sub-card',
+ 'fields_options' => [
+ 'border' => [
+ 'default' => 'solid',
+ ],
+ 'width' => [
+ 'default' => [
+ 'top' => '1',
+ 'right' => '1',
+ 'bottom' => '1',
+ 'left' => '1',
+ 'isLinked' => true,
+ ],
+ ],
+ 'color' => [
+ 'default' => '#e5e7eb',
+ ],
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'card_border_radius',
+ [
+ 'label' => __( 'Border Radius', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', '%' ],
+ 'default' => [
+ 'top' => '12',
+ 'right' => '12',
+ 'bottom' => '12',
+ 'left' => '12',
+ 'isLinked' => true,
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-card' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Box_Shadow::get_type(),
+ [
+ 'name' => 'card_box_shadow',
+ 'selector' => '{{WRAPPER}} .wpuf-sub-card',
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'card_padding',
+ [
+ 'label' => __( 'Card Padding', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'default' => [
+ 'top' => '24',
+ 'right' => '24',
+ 'bottom' => '24',
+ 'left' => '24',
+ 'isLinked' => true,
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-card' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'card_margin',
+ [
+ 'label' => __( 'Card Margin', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-card' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'cards_gap',
+ [
+ 'label' => __( 'Gap Between Cards', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px' ],
+ 'range' => [ 'px' => [ 'min' => 0, 'max' => 100 ] ],
+ 'default' => [
+ 'size' => '20',
+ 'unit' => 'px',
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-subscription-plans-grid' => 'gap: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register plan name style controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_plan_name_style_controls() {
+ $this->start_controls_section(
+ 'section_plan_name_style',
+ [
+ 'label' => __( 'Plan Name', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_control(
+ 'plan_name_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#111827',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-plan-name' => 'color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Typography::get_type(),
+ [
+ 'name' => 'plan_name_typography',
+ 'selector' => '{{WRAPPER}} .wpuf-sub-plan-name',
+ 'fields_options' => [
+ 'font_size' => [
+ 'default' => [
+ 'size' => '24',
+ 'unit' => 'px',
+ ],
+ ],
+ 'font_weight' => [
+ 'default' => '700',
+ ],
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'plan_name_align',
+ [
+ 'label' => __( 'Text Alignment', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::CHOOSE,
+ 'options' => [
+ 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-left' ],
+ 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-center' ],
+ 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-right' ],
+ ],
+ 'default' => 'left',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-plan-name' => 'text-align: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'plan_name_margin_bottom',
+ [
+ 'label' => __( 'Margin Bottom', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px' ],
+ 'range' => [ 'px' => [ 'min' => 0, 'max' => 50 ] ],
+ 'default' => [
+ 'size' => '16',
+ 'unit' => 'px',
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-plan-name' => 'margin-bottom: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register price style controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_price_style_controls() {
+ $this->start_controls_section(
+ 'section_price_style',
+ [
+ 'label' => __( 'Price', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_control(
+ 'price_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#111827',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-price' => 'color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'currency_color',
+ [
+ 'label' => __( 'Currency Symbol Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#6b7280',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-currency' => 'color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'billing_cycle_color',
+ [
+ 'label' => __( 'Billing Cycle Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#6b7280',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-billing-cycle' => 'color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'billing_cycle_font_size',
+ [
+ 'label' => __( 'Billing Cycle Text Size', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px', 'em' ],
+ 'range' => [ 'px' => [ 'min' => 8, 'max' => 50 ] ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-billing-cycle' => 'font-size: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Typography::get_type(),
+ [
+ 'name' => 'price_typography',
+ 'selector' => '{{WRAPPER}} .wpuf-sub-price',
+ 'fields_options' => [
+ 'font_size' => [
+ 'default' => [
+ 'size' => '36',
+ 'unit' => 'px',
+ ],
+ ],
+ 'font_weight' => [
+ 'default' => '700',
+ ],
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'price_align',
+ [
+ 'label' => __( 'Text Alignment', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::CHOOSE,
+ 'options' => [
+ 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-left' ],
+ 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-center' ],
+ 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-right' ],
+ ],
+ 'default' => 'left',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-price-wrapper' => 'text-align: {{VALUE}};',
+ '{{WRAPPER}} .wpuf-sub-price' => 'justify-content: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'price_margin_bottom',
+ [
+ 'label' => __( 'Margin Bottom', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px' ],
+ 'range' => [ 'px' => [ 'min' => 0, 'max' => 50 ] ],
+ 'default' => [
+ 'size' => '20',
+ 'unit' => 'px',
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-price-wrapper' => 'margin-bottom: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register trial description style controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_trial_description_style_controls() {
+ $this->start_controls_section(
+ 'section_trial_style',
+ [
+ 'label' => __( 'Trial Description', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_control(
+ 'trial_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#059669',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-trial-description' => 'color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Typography::get_type(),
+ [
+ 'name' => 'trial_typography',
+ 'selector' => '{{WRAPPER}} .wpuf-sub-trial-description',
+ 'fields_options' => [
+ 'font_size' => [
+ 'default' => [
+ 'size' => '14',
+ 'unit' => 'px',
+ ],
+ ],
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'trial_font_size',
+ [
+ 'label' => __( 'Text Size', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px', 'em' ],
+ 'range' => [ 'px' => [ 'min' => 8, 'max' => 50 ] ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-trial-description' => 'font-size: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'trial_align',
+ [
+ 'label' => __( 'Text Alignment', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::CHOOSE,
+ 'options' => [
+ 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-left' ],
+ 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-center' ],
+ 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-right' ],
+ ],
+ 'default' => 'left',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-trial-description' => 'text-align: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register features list style controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_features_list_style_controls() {
+ $this->start_controls_section(
+ 'section_features_style',
+ [
+ 'label' => __( 'Features List', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_control(
+ 'features_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#4b5563',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-features-list' => 'color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'icon_color',
+ [
+ 'label' => __( 'Icon Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#10b981',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-feature-icon' => 'fill: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'icon_size',
+ [
+ 'label' => __( 'Icon Size', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px' ],
+ 'range' => [ 'px' => [ 'min' => 10, 'max' => 50 ] ],
+ 'default' => [
+ 'size' => '20',
+ 'unit' => 'px',
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-feature-icon' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Typography::get_type(),
+ [
+ 'name' => 'features_typography',
+ 'selector' => '{{WRAPPER}} .wpuf-sub-features-list',
+ 'fields_options' => [
+ 'font_size' => [
+ 'default' => [
+ 'size' => '14',
+ 'unit' => 'px',
+ ],
+ ],
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'features_line_spacing',
+ [
+ 'label' => __( 'Line Spacing', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px' ],
+ 'range' => [ 'px' => [ 'min' => 0, 'max' => 50 ] ],
+ 'default' => [
+ 'size' => '12',
+ 'unit' => 'px',
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-feature-item' => 'margin-bottom: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'features_margin_bottom',
+ [
+ 'label' => __( 'Margin Bottom', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px' ],
+ 'range' => [ 'px' => [ 'min' => 0, 'max' => 50 ] ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-features-list' => 'margin-bottom: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register button style controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_button_style_controls() {
+ $this->start_controls_section(
+ 'section_button_style',
+ [
+ 'label' => __( 'Subscribe Button', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Typography::get_type(),
+ [
+ 'name' => 'button_typography',
+ 'selector' => '{{WRAPPER}} .wpuf-sub-button',
+ 'fields_options' => [
+ 'font_size' => [
+ 'default' => [
+ 'size' => '16',
+ 'unit' => 'px',
+ ],
+ ],
+ 'font_weight' => [
+ 'default' => '600',
+ ],
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'button_font_size',
+ [
+ 'label' => __( 'Text Size', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px', 'em', 'rem' ],
+ 'range' => [
+ 'px' => [ 'min' => 8, 'max' => 50 ],
+ 'em' => [ 'min' => 0.5, 'max' => 5 ],
+ 'rem' => [ 'min' => 0.5, 'max' => 5 ],
+ ],
+ 'default' => [
+ 'size' => '1',
+ 'unit' => 'rem',
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-button' => 'font-size: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'button_align',
+ [
+ 'label' => __( 'Alignment', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::CHOOSE,
+ 'options' => [
+ 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-left' ],
+ 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-center' ],
+ 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-right' ],
+ ],
+ 'default' => 'center',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-button-wrapper' => 'text-align: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->start_controls_tabs( 'tabs_button_style' );
+
+ $this->start_controls_tab( 'tab_button_normal', [ 'label' => __( 'Normal', 'wp-user-frontend' ) ] );
+
+ $this->add_control(
+ 'button_text_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#ffffff',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-button' => 'color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'button_bg_color',
+ [
+ 'label' => __( 'Background Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#64748b',
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-button' => 'background-color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Border::get_type(),
+ [
+ 'name' => 'button_border',
+ 'selector' => '{{WRAPPER}} .wpuf-sub-button',
+ 'fields_options' => [
+ 'border' => [
+ 'default' => 'solid',
+ ],
+ 'width' => [
+ 'default' => [
+ 'top' => '1',
+ 'right' => '1',
+ 'bottom' => '1',
+ 'left' => '1',
+ 'isLinked' => true,
+ ],
+ ],
+ 'color' => [
+ 'default' => 'transparent',
+ ],
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'button_border_radius',
+ [
+ 'label' => __( 'Border Radius', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', '%' ],
+ 'default' => [
+ 'top' => '5',
+ 'right' => '5',
+ 'bottom' => '5',
+ 'left' => '5',
+ 'isLinked' => true,
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'button_padding',
+ [
+ 'label' => __( 'Padding', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'default' => [
+ 'top' => '5',
+ 'right' => '20',
+ 'bottom' => '5',
+ 'left' => '20',
+ 'isLinked' => false,
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->end_controls_tab();
+
+ $this->start_controls_tab( 'tab_button_hover', [ 'label' => __( 'Hover', 'wp-user-frontend' ) ] );
+
+ $this->add_control(
+ 'button_hover_text_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-button:hover' => 'color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'button_hover_bg_color',
+ [
+ 'label' => __( 'Background Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-button:hover' => 'background-color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'button_hover_border_color',
+ [
+ 'label' => __( 'Border Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-sub-button:hover' => 'border-color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->end_controls_tab();
+
+ $this->end_controls_tabs();
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Retrieve subscription plans based on widget settings
+ *
+ * @since WPUF_SINCE
+ *
+ * @param array $settings Widget settings.
+ * @return array Array of subscription packs
+ */
+ protected function get_subscription_plans( $settings ) {
+ $args = [
+ 'post_type' => 'wpuf_subscription',
+ 'posts_per_page' => -1,
+ 'post_status' => 'publish',
+ ];
+
+ $order_by = isset( $settings['order_by'] ) ? $settings['order_by'] : 'custom';
+
+ switch ( $order_by ) {
+ case 'id':
+ $args['orderby'] = 'ID';
+ $args['order'] = 'ASC';
+ break;
+ case 'price_asc':
+ $args['orderby'] = 'meta_value_num';
+ $args['meta_key'] = '_billing_amount';
+ $args['order'] = 'ASC';
+ break;
+ case 'price_desc':
+ $args['orderby'] = 'meta_value_num';
+ $args['meta_key'] = '_billing_amount';
+ $args['order'] = 'DESC';
+ break;
+ case 'custom':
+ default:
+ $args['meta_key'] = '_sort_order';
+ $args['orderby'] = [ 'meta_value_num' => 'ASC', 'title' => 'ASC' ];
+ break;
+ }
+
+ $packs = get_posts( $args );
+
+ if ( ! empty( $packs ) ) {
+ foreach ( $packs as $key => $post ) {
+ $packs[ $key ]->meta_value = wpuf()->subscription->get_subscription_meta( $post->ID, $post );
+ }
+ }
+
+ return $packs;
+ }
+
+ /**
+ * Get the CSS class for plans per row
+ *
+ * @since WPUF_SINCE
+ *
+ * @param string $plans_per_row Number of plans per row.
+ * @return string CSS class
+ */
+ protected function get_plans_per_row_class( $plans_per_row ) {
+ return 'wpuf-sub-plans-' . $plans_per_row;
+ }
+
+ /**
+ * Render the widget output on the frontend
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function render() {
+ $settings = $this->get_settings_for_display();
+
+ $packs = $this->get_subscription_plans( $settings );
+
+ $is_elementor_editor = $this->is_editor_render();
+
+ // Show empty state in editor if no plans
+ if ( $is_elementor_editor && empty( $packs ) ) {
+ $this->render_empty_state();
+ return;
+ }
+
+ // Show nothing in frontend if no plans
+ if ( ! $is_elementor_editor && empty( $packs ) ) {
+ return;
+ }
+
+ $plans_per_row = isset( $settings['plans_per_row'] ) ? $settings['plans_per_row'] : '3';
+ $grid_class = $this->get_plans_per_row_class( $plans_per_row );
+
+ $this->add_render_attribute(
+ 'wrapper',
+ [
+ 'class' => [ 'wpuf-subscription-plans-wrapper', $grid_class ],
+ ]
+ );
+
+ $user_id = get_current_user_id();
+ $current_pack = wpuf()->subscription->get_user_pack( $user_id );
+ $current_pack_id = isset( $current_pack['pack_id'] ) ? $current_pack['pack_id'] : '';
+ $current_pack_status = isset( $current_pack['status'] ) ? $current_pack['status'] : '';
+
+ echo 'get_render_attribute_string( 'wrapper' ) . '>';
+ echo '
';
+
+ foreach ( $packs as $pack ) :
+ $this->render_plan_card( $pack, $current_pack_id, $current_pack_status );
+ endforeach;
+
+ echo '
';
+ echo '
';
+
+ if ( $is_elementor_editor ) {
+ $this->render_toggle_script();
+ }
+ }
+
+ /**
+ * Render empty state for Elementor editor
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function render_empty_state() {
+ echo '';
+ echo '
';
+ echo '
';
+ echo '
';
+ echo '
';
+ echo '
' . esc_html__( 'No subscription plans available.', 'wp-user-frontend' ) . '
';
+ echo '
' . esc_html__( 'Create a subscription plan in WPUF settings.', 'wp-user-frontend' ) . '
';
+ echo '
';
+ echo '
';
+ }
+
+ /**
+ * Render a single plan card
+ *
+ * @since WPUF_SINCE
+ *
+ * @param \WP_Post $pack The subscription plan post object.
+ * @param string $current_pack_id Current active pack ID.
+ * @param string $current_pack_status Current pack status.
+ * @return void
+ */
+ protected function render_plan_card( $pack, $current_pack_id, $current_pack_status ) {
+ $settings = $this->get_settings_for_display();
+ $billing_amount = isset( $pack->meta_value['billing_amount'] ) ? floatval( $pack->meta_value['billing_amount'] ) : 0;
+ $recurring_pay = wpuf_is_checkbox_or_toggle_on( $pack->meta_value['recurring_pay'] ?? '' );
+ $trial_status = wpuf_is_checkbox_or_toggle_on( $pack->meta_value['trial_status'] ?? '' );
+ $billing_cycle_number = isset( $pack->meta_value['billing_cycle_number'] ) ? $pack->meta_value['billing_cycle_number'] : 1;
+ $cycle_period = isset( $pack->meta_value['cycle_period'] ) ? $pack->meta_value['cycle_period'] : 'month';
+ $trial_duration = isset( $pack->meta_value['trial_duration'] ) ? $pack->meta_value['trial_duration'] : 0;
+ $trial_duration_type = isset( $pack->meta_value['trial_duration_type'] ) ? $pack->meta_value['trial_duration_type'] : 'day';
+
+ $this->add_render_attribute(
+ 'card-' . $pack->ID,
+ [
+ 'class' => [ 'wpuf-sub-card', 'wpuf-sub-card-' . $pack->ID ],
+ ]
+ );
+
+ echo 'get_render_attribute_string( 'card-' . $pack->ID ) . '>';
+
+ // Plan Name
+ echo '
' . esc_html( $pack->post_title ) . '
';
+
+ // Description
+ if ( ! empty( $pack->post_content ) ) {
+ echo '
' . wp_kses_post( wpautop( $pack->post_content ) ) . '
';
+ }
+
+ // Price Section
+ echo '
';
+ if ( $billing_amount > 0 ) {
+ $currency_symbol = wpuf_get_currency( 'symbol' );
+ $amount_formatted = number_format( $billing_amount, 2, '.', '' );
+
+ echo '
';
+ echo '' . esc_html( $currency_symbol ) . '';
+ echo '' . esc_html( $amount_formatted ) . '';
+
+ if ( $recurring_pay ) {
+ $cycle_label = wpuf()->subscription->get_cycle_label( $cycle_period, $billing_cycle_number );
+ $billing_text = sprintf( __( 'Every %s %s', 'wp-user-frontend' ), $billing_cycle_number, $cycle_label );
+ echo '' . esc_html( $billing_text ) . '';
+ } else {
+ echo '' . esc_html__( 'One time payment', 'wp-user-frontend' ) . '';
+ }
+ echo '
';
+ } else {
+ echo '
' . esc_html__( 'Free', 'wp-user-frontend' ) . '
';
+ }
+ echo '
';
+
+ // Trial Description
+ if ( $billing_amount > 0 && $recurring_pay && $trial_status && $trial_duration > 0 ) {
+ $duration = _n( $trial_duration_type, $trial_duration_type . 's', $trial_duration, 'wp-user-frontend' );
+ $trial_text = sprintf( __( 'Trial available for first %1$s %2$s', 'wp-user-frontend' ), $trial_duration, $duration );
+ echo '
' . esc_html( $trial_text ) . '
';
+ }
+
+ // Button
+ $this->render_button( $pack, $current_pack_id, $current_pack_status, $billing_amount );
+
+ // Features List
+ $this->render_features_list( $pack );
+
+ echo '
';
+ }
+
+ /**
+ * Render the subscribe button
+ *
+ * @since WPUF_SINCE
+ *
+ * @param \WP_Post $pack The subscription plan post object.
+ * @param string $current_pack_id Current active pack ID.
+ * @param string $current_pack_status Current pack status.
+ * @param float $billing_amount The billing amount.
+ * @return void
+ */
+ protected function render_button( $pack, $current_pack_id, $current_pack_status, $billing_amount ) {
+ $user_id = get_current_user_id();
+
+ $is_completed = ( $current_pack_id == $pack->ID && 'completed' === $current_pack_status );
+
+ // Get button labels from WPUF settings
+ if ( ! is_user_logged_in() ) {
+ $button_text = wpuf_get_option( 'logged_out_label', 'wpuf_subscription_settings', '' );
+ $button_text = $button_text ? $button_text : __( 'Sign Up', 'wp-user-frontend' );
+ } elseif ( $billing_amount === 0.0 || $billing_amount === '0.00' ) {
+ $button_text = wpuf_get_option( 'free_label', 'wpuf_subscription_settings', '' );
+ $button_text = $button_text ? $button_text : __( 'Free', 'wp-user-frontend' );
+ } else {
+ $button_text = wpuf_get_option( 'logged_in_label', 'wpuf_subscription_settings', '' );
+ $button_text = $button_text ? $button_text : __( 'Buy Now', 'wp-user-frontend' );
+ }
+
+ // Build button URL
+ if ( ! is_user_logged_in() ) {
+ $query_args = [
+ 'action' => 'register',
+ 'type' => 'wpuf_sub',
+ 'pack_id' => $pack->ID,
+ ];
+ $button_url = wp_registration_url();
+ } else {
+ $query_args = [
+ 'action' => 'wpuf_pay',
+ 'type' => 'pack',
+ 'pack_id' => $pack->ID,
+ ];
+ $button_url = get_permalink( wpuf_get_option( 'payment_page', 'wpuf_payment' ) );
+ }
+
+ $button_url = add_query_arg( $query_args, $button_url );
+
+ $this->add_render_attribute(
+ 'button-' . $pack->ID,
+ [
+ 'class' => [ 'wpuf-sub-button', 'wpuf-sub-button-' . $pack->ID ],
+ 'href' => esc_url( $button_url ),
+ ]
+ );
+
+ if ( $is_completed ) {
+ $this->add_render_attribute( 'button-' . $pack->ID, 'href', 'javascript:void(0)' );
+ $this->add_render_attribute( 'button-' . $pack->ID, 'class', 'wpuf-sub-button-disabled' );
+ }
+
+ echo '';
+ }
+
+ /**
+ * Render the features list for a plan
+ *
+ * @since WPUF_SINCE
+ *
+ * @param \WP_Post $pack The subscription plan post object.
+ * @return void
+ */
+ protected function render_features_list( $pack ) {
+ $features_list = [];
+
+ // Check if custom features are set
+ if ( isset( $pack->meta_value['features'] ) && is_array( $pack->meta_value['features'] ) && ! empty( $pack->meta_value['features'] ) ) {
+ foreach ( $pack->meta_value['features'] as $feature ) {
+ $features_list[] = esc_html( $feature );
+ }
+ } else {
+ // Build features from subscription settings
+ $post_type_limits = isset( $pack->meta_value['_post_type_name'] ) ? maybe_unserialize( $pack->meta_value['_post_type_name'] ) : [];
+ $additional_cpt = isset( $pack->meta_value['additional_cpt_options'] ) ? maybe_unserialize( $pack->meta_value['additional_cpt_options'] ) : [];
+ $all_limits = array_merge( (array) $post_type_limits, (array) $additional_cpt );
+
+ // Posts limit
+ if ( isset( $all_limits['post'] ) && '0' !== $all_limits['post'] ) {
+ if ( '-1' === $all_limits['post'] ) {
+ $features_list[] = __( 'Unlimited posts', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d posts allowed', 'wp-user-frontend' ), intval( $all_limits['post'] ) );
+ }
+ }
+
+ // Pages limit
+ if ( isset( $all_limits['page'] ) && '0' !== $all_limits['page'] ) {
+ if ( '-1' === $all_limits['page'] ) {
+ $features_list[] = __( 'Unlimited pages', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d pages allowed', 'wp-user-frontend' ), intval( $all_limits['page'] ) );
+ }
+ }
+
+ // User Requests limit
+ if ( isset( $all_limits['user_request'] ) && '0' !== $all_limits['user_request'] ) {
+ if ( '-1' === $all_limits['user_request'] ) {
+ $features_list[] = __( 'Unlimited user requests', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d user requests allowed', 'wp-user-frontend' ), intval( $all_limits['user_request'] ) );
+ }
+ }
+
+ // WooCommerce Products limit
+ if ( isset( $all_limits['product'] ) && '0' !== $all_limits['product'] ) {
+ if ( '-1' === $all_limits['product'] ) {
+ $features_list[] = __( 'Unlimited products', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d products allowed', 'wp-user-frontend' ), intval( $all_limits['product'] ) );
+ }
+ }
+
+ // Reusable Blocks limit
+ if ( isset( $all_limits['wp_block'] ) && '0' !== $all_limits['wp_block'] ) {
+ if ( '-1' === $all_limits['wp_block'] ) {
+ $features_list[] = __( 'Unlimited reusable blocks', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d reusable blocks allowed', 'wp-user-frontend' ), intval( $all_limits['wp_block'] ) );
+ }
+ }
+
+ // Templates limit
+ if ( isset( $all_limits['wp_template'] ) && '0' !== $all_limits['wp_template'] ) {
+ if ( '-1' === $all_limits['wp_template'] ) {
+ $features_list[] = __( 'Unlimited templates', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d templates allowed', 'wp-user-frontend' ), intval( $all_limits['wp_template'] ) );
+ }
+ }
+
+ // Template Parts limit
+ if ( isset( $all_limits['wp_template_part'] ) && '0' !== $all_limits['wp_template_part'] ) {
+ if ( '-1' === $all_limits['wp_template_part'] ) {
+ $features_list[] = __( 'Unlimited template parts', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d template parts allowed', 'wp-user-frontend' ), intval( $all_limits['wp_template_part'] ) );
+ }
+ }
+
+ // Navigation Menus limit
+ if ( isset( $all_limits['wp_navigation'] ) && '0' !== $all_limits['wp_navigation'] ) {
+ if ( '-1' === $all_limits['wp_navigation'] ) {
+ $features_list[] = __( 'Unlimited navigation menus', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d navigation menus allowed', 'wp-user-frontend' ), intval( $all_limits['wp_navigation'] ) );
+ }
+ }
+
+ // Global Styles limit
+ if ( isset( $all_limits['wp_global_styles'] ) && '0' !== $all_limits['wp_global_styles'] ) {
+ if ( '-1' === $all_limits['wp_global_styles'] ) {
+ $features_list[] = __( 'Unlimited global styles', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d global styles allowed', 'wp-user-frontend' ), intval( $all_limits['wp_global_styles'] ) );
+ }
+ }
+
+ // Font Families limit
+ if ( isset( $all_limits['wp_font_family'] ) && '0' !== $all_limits['wp_font_family'] ) {
+ if ( '-1' === $all_limits['wp_font_family'] ) {
+ $features_list[] = __( 'Unlimited font families', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d font families allowed', 'wp-user-frontend' ), intval( $all_limits['wp_font_family'] ) );
+ }
+ }
+
+ // Font Faces limit
+ if ( isset( $all_limits['wp_font_face'] ) && '0' !== $all_limits['wp_font_face'] ) {
+ if ( '-1' === $all_limits['wp_font_face'] ) {
+ $features_list[] = __( 'Unlimited font faces', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d font faces allowed', 'wp-user-frontend' ), intval( $all_limits['wp_font_face'] ) );
+ }
+ }
+
+ // Product Variations limit
+ if ( isset( $all_limits['product_variation'] ) && '0' !== $all_limits['product_variation'] ) {
+ if ( '-1' === $all_limits['product_variation'] ) {
+ $features_list[] = __( 'Unlimited product variations', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d product variations allowed', 'wp-user-frontend' ), intval( $all_limits['product_variation'] ) );
+ }
+ }
+
+ // Shop Orders limit
+ if ( isset( $all_limits['shop_order'] ) && '0' !== $all_limits['shop_order'] ) {
+ if ( '-1' === $all_limits['shop_order'] ) {
+ $features_list[] = __( 'Unlimited shop orders', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d shop orders allowed', 'wp-user-frontend' ), intval( $all_limits['shop_order'] ) );
+ }
+ }
+
+ // Shop Refunds limit
+ if ( isset( $all_limits['shop_order_refund'] ) && '0' !== $all_limits['shop_order_refund'] ) {
+ if ( '-1' === $all_limits['shop_order_refund'] ) {
+ $features_list[] = __( 'Unlimited shop refunds', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d shop refunds allowed', 'wp-user-frontend' ), intval( $all_limits['shop_order_refund'] ) );
+ }
+ }
+
+ // Shop Coupons limit
+ if ( isset( $all_limits['shop_coupon'] ) && '0' !== $all_limits['shop_coupon'] ) {
+ if ( '-1' === $all_limits['shop_coupon'] ) {
+ $features_list[] = __( 'Unlimited shop coupons', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d shop coupons allowed', 'wp-user-frontend' ), intval( $all_limits['shop_coupon'] ) );
+ }
+ }
+
+ // Featured items limit
+ if ( isset( $pack->meta_value['_total_feature_item'] ) && '0' !== $pack->meta_value['_total_feature_item'] ) {
+ if ( '-1' === $pack->meta_value['_total_feature_item'] ) {
+ $features_list[] = __( 'Unlimited featured items', 'wp-user-frontend' );
+ } else {
+ $features_list[] = sprintf( __( '%d featured items', 'wp-user-frontend' ), intval( $pack->meta_value['_total_feature_item'] ) );
+ }
+ }
+
+ // Post expiration
+ if ( isset( $pack->meta_value['_enable_post_expiration'] ) && 'yes' === $pack->meta_value['_enable_post_expiration'] ) {
+ $expiry_period = isset( $pack->meta_value['_post_expiration_number'] ) ? intval( $pack->meta_value['_post_expiration_number'] ) : 0;
+ $expiry_type = isset( $pack->meta_value['_post_expiration_period'] ) ? $pack->meta_value['_post_expiration_period'] : 'day';
+
+ if ( $expiry_period > 0 ) {
+ $features_list[] = sprintf( __( 'Posts expire after %d %s', 'wp-user-frontend' ), $expiry_period, $expiry_type . ( $expiry_period > 1 ? 's' : '' ) );
+ } else {
+ $features_list[] = __( 'Post expiration enabled', 'wp-user-frontend' );
+ }
+ }
+
+ // Recurring payment
+ if ( wpuf_is_checkbox_or_toggle_on( $pack->meta_value['recurring_pay'] ?? '' ) ) {
+ $features_list[] = __( 'Recurring subscription', 'wp-user-frontend' );
+ }
+
+ // Trial period
+ if ( wpuf_is_checkbox_or_toggle_on( $pack->meta_value['trial_status'] ?? '' ) ) {
+ $trial_duration = isset( $pack->meta_value['trial_duration'] ) ? intval( $pack->meta_value['trial_duration'] ) : 0;
+ $trial_type = isset( $pack->meta_value['trial_duration_type'] ) ? $pack->meta_value['trial_duration_type'] : 'day';
+
+ if ( $trial_duration > 0 ) {
+ $features_list[] = sprintf( __( '%d %s free trial', 'wp-user-frontend' ), $trial_duration, $trial_type . ( $trial_duration > 1 ? 's' : '' ) );
+ } else {
+ $features_list[] = __( 'Free trial available', 'wp-user-frontend' );
+ }
+ }
+
+ // Mail notification on expiry
+ if ( isset( $pack->meta_value['_enable_mail_after_expired'] ) && 'yes' === $pack->meta_value['_enable_mail_after_expired'] ) {
+ $features_list[] = __( 'Email notifications on post expiry', 'wp-user-frontend' );
+ }
+
+ // If no features found, show a basic feature
+ if ( empty( $features_list ) ) {
+ $features_list[] = __( 'Full website access', 'wp-user-frontend' );
+ }
+ }
+
+ // Render features list
+ if ( ! empty( $features_list ) ) {
+ $features_count = count( $features_list );
+ $initial_display_count = 5;
+ $pack_id = $pack->ID;
+
+ echo '';
+
+ foreach ( $features_list as $index => $feature ) {
+ $is_hidden = $index >= $initial_display_count ? ' wpuf-sub-feature-hidden' : '';
+
+ echo '- ';
+ echo '';
+ echo '' . esc_html( $feature ) . '';
+ echo '
';
+ }
+
+ echo '
';
+
+ // Show See More/Less button if features exceed initial display count
+ if ( $features_count > $initial_display_count ) {
+ $hidden_count = $features_count - $initial_display_count;
+
+ echo '';
+ echo '';
+ echo '';
+ echo '
';
+ }
+ }
+ }
+
+ /**
+ * Render toggle script for expandable features
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function render_toggle_script() {
+ ?>
+
+ editor ) && \Elementor\Plugin::$instance->editor->is_edit_mode() )
+ || ( isset( \Elementor\Plugin::$instance->preview ) && \Elementor\Plugin::$instance->preview->is_preview_mode() )
+ );
+ }
+
+ /**
+ * Render the widget output in the editor
+ *
+ * When empty, Elementor will fall back to using the render() method for
+ * both frontend and editor preview.
+ *
+ * @since WPUF_SINCE
+ *
+ * @access protected
+ */
+ protected function content_template() {}
+}
diff --git a/includes/Integrations/Elementor/Widget.php b/includes/Integrations/Elementor/Widget.php
new file mode 100644
index 000000000..b034f4c19
--- /dev/null
+++ b/includes/Integrations/Elementor/Widget.php
@@ -0,0 +1,1280 @@
+start_controls_section(
+ 'section_content',
+ [
+ 'label' => __( 'Content', 'wp-user-frontend' ),
+ ]
+ );
+
+ $this->add_control(
+ 'form_id',
+ [
+ 'label' => __( 'Select Form', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SELECT,
+ 'default' => '',
+ 'options' => $this->get_wpuf_forms(),
+ ]
+ );
+
+ $this->end_controls_section();
+
+ // Style Tab
+ $this->register_container_style_controls();
+ $this->register_label_style_controls();
+ $this->register_input_style_controls();
+ $this->register_placeholder_style_controls();
+ $this->register_radio_checkbox_style_controls();
+ $this->register_upload_button_style_controls();
+ $this->register_submit_button_style_controls();
+
+ /**
+ * Fires after the widget has registered its style controls.
+ *
+ * Use this to add additional style sections (e.g. for Pro features like multistep).
+ *
+ * @since WPUF_SINCE
+ *
+ * @param \Elementor\Widget_Base $this The widget instance.
+ */
+ do_action( 'wpuf_elementor_widget_register_style_controls', $this );
+ }
+
+ /**
+ * Retrieve all published WPUF forms
+ *
+ * @since WPUF_SINCE
+ *
+ * @return array Array of forms formatted as select options
+ */
+ protected function get_wpuf_forms() {
+ $forms = get_posts( [
+ 'post_type' => 'wpuf_forms',
+ 'posts_per_page' => -1,
+ 'post_status' => 'publish',
+ ] );
+
+ $options = [ '' => __( 'Select a Form', 'wp-user-frontend' ) ];
+
+ if ( ! empty( $forms ) ) {
+ foreach ( $forms as $form ) {
+ $options[ $form->ID ] = $form->post_title;
+ }
+ }
+
+ /**
+ * Filters the form options shown in the widget's form dropdown.
+ *
+ * @since WPUF_SINCE
+ *
+ * @param array $options Associative array of form_id => form_title.
+ * @param \Elementor\Widget_Base $this The widget instance.
+ */
+ return apply_filters( 'wpuf_elementor_form_options', $options, $this );
+ }
+
+ /**
+ * Register container style controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_container_style_controls() {
+ $this->start_controls_section(
+ 'section_container_style',
+ [
+ 'label' => __( 'Form Container', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Background::get_type(),
+ [
+ 'name' => 'container_background',
+ 'label' => __( 'Background', 'wp-user-frontend' ),
+ 'types' => [ 'classic', 'gradient' ],
+ 'selector' => '{{WRAPPER}} .wpuf-elementor-widget-wrapper',
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'container_max_width',
+ [
+ 'label' => __( 'Max Width', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'range' => [
+ 'px' => [ 'min' => 10, 'max' => 1500 ],
+ 'em' => [ 'min' => 1, 'max' => 80 ],
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-elementor-widget-wrapper' => 'width: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'container_alignment',
+ [
+ 'label' => __( 'Alignment', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::CHOOSE,
+ 'options' => [
+ 'default' => [
+ 'title' => __( 'Default', 'wp-user-frontend' ),
+ 'icon' => 'eicon-ban',
+ ],
+ 'left' => [
+ 'title' => __( 'Left', 'wp-user-frontend' ),
+ 'icon' => 'eicon-h-align-left',
+ ],
+ 'center' => [
+ 'title' => __( 'Center', 'wp-user-frontend' ),
+ 'icon' => 'eicon-h-align-center',
+ ],
+ 'right' => [
+ 'title' => __( 'Right', 'wp-user-frontend' ),
+ 'icon' => 'eicon-h-align-right',
+ ],
+ ],
+ 'default' => 'default',
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'container_padding',
+ [
+ 'label' => __( 'Padding', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-elementor-widget-wrapper' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'container_margin',
+ [
+ 'label' => __( 'Margin', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-elementor-widget-wrapper' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Border::get_type(),
+ [
+ 'name' => 'container_border',
+ 'selector' => '{{WRAPPER}} .wpuf-elementor-widget-wrapper',
+ ]
+ );
+
+ $this->add_control(
+ 'container_border_radius',
+ [
+ 'label' => __( 'Border Radius', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', '%' ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-elementor-widget-wrapper' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Box_Shadow::get_type(),
+ [
+ 'name' => 'container_box_shadow',
+ 'selector' => '{{WRAPPER}} .wpuf-elementor-widget-wrapper',
+ ]
+ );
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register label style controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_label_style_controls() {
+ $this->start_controls_section(
+ 'section_label_style',
+ [
+ 'label' => __( 'Labels', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_control(
+ 'label_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-form .wpuf-label' => 'color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Typography::get_type(),
+ [
+ 'name' => 'label_typography',
+ 'selector' => '{{WRAPPER}} .wpuf-form .wpuf-label',
+ ]
+ );
+
+ $this->add_control(
+ 'label_asterisk_color',
+ [
+ 'label' => __( 'Asterisk Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-form .wpuf-label .required' => 'color: {{VALUE}};',
+ ],
+ 'separator' => 'before',
+ ]
+ );
+
+ $this->add_control(
+ 'label_asterisk_size',
+ [
+ 'label' => __( 'Asterisk Size', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'range' => [
+ 'px' => [ 'min' => 0, 'max' => 30, 'step' => 1 ],
+ '%' => [ 'min' => 0, 'max' => 30, 'step' => 1 ],
+ ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-form .wpuf-label .required' => 'font-size: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register input field style controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_input_style_controls() {
+ $input_selector = '{{WRAPPER}} .wpuf-form input[type="text"], {{WRAPPER}} .wpuf-form input[type="email"], {{WRAPPER}} .wpuf-form input[type="url"], {{WRAPPER}} .wpuf-form input[type="password"], {{WRAPPER}} .wpuf-form input[type="number"], {{WRAPPER}} .wpuf-form textarea, {{WRAPPER}} .wpuf-form select';
+
+ $this->start_controls_section(
+ 'section_input_style',
+ [
+ 'label' => __( 'Input & Textarea', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'input_alignment',
+ [
+ 'label' => __( 'Alignment', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::CHOOSE,
+ 'options' => [
+ 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-left' ],
+ 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-center' ],
+ 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-text-align-right' ],
+ ],
+ 'selectors' => [ $input_selector => 'text-align: {{VALUE}};' ],
+ ]
+ );
+
+ $this->start_controls_tabs( 'tabs_input_style' );
+
+ $this->start_controls_tab( 'tab_input_normal', [ 'label' => __( 'Normal', 'wp-user-frontend' ) ] );
+
+ $this->add_control(
+ 'input_bg_color',
+ [
+ 'label' => __( 'Background Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [ $input_selector => 'background-color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->add_control(
+ 'input_text_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [ $input_selector => 'color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Typography::get_type(),
+ [ 'name' => 'input_typography', 'selector' => $input_selector ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Border::get_type(),
+ [ 'name' => 'input_border', 'selector' => $input_selector ]
+ );
+
+ $this->add_control(
+ 'input_border_radius',
+ [
+ 'label' => __( 'Border Radius', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', '%' ],
+ 'selectors' => [ $input_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'input_padding',
+ [
+ 'label' => __( 'Padding', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'selectors' => [ $input_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Box_Shadow::get_type(),
+ [
+ 'name' => 'input_box_shadow',
+ 'selector' => $input_selector,
+ 'separator' => 'before',
+ ]
+ );
+
+ $this->end_controls_tab();
+
+ $this->start_controls_tab( 'tab_input_focus', [ 'label' => __( 'Focus', 'wp-user-frontend' ) ] );
+
+ $this->add_control(
+ 'input_focus_bg_color',
+ [
+ 'label' => __( 'Background Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-form input[type="text"]:focus, {{WRAPPER}} .wpuf-form input[type="email"]:focus, {{WRAPPER}} .wpuf-form input[type="url"]:focus, {{WRAPPER}} .wpuf-form input[type="password"]:focus, {{WRAPPER}} .wpuf-form input[type="number"]:focus, {{WRAPPER}} .wpuf-form textarea:focus, {{WRAPPER}} .wpuf-form select:focus' => 'background-color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Border::get_type(),
+ [
+ 'name' => 'input_focus_border',
+ 'selector' => '{{WRAPPER}} .wpuf-form input[type="text"]:focus, {{WRAPPER}} .wpuf-form input[type="email"]:focus, {{WRAPPER}} .wpuf-form input[type="url"]:focus, {{WRAPPER}} .wpuf-form input[type="password"]:focus, {{WRAPPER}} .wpuf-form input[type="number"]:focus, {{WRAPPER}} .wpuf-form textarea:focus, {{WRAPPER}} .wpuf-form select:focus',
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Box_Shadow::get_type(),
+ [
+ 'name' => 'input_focus_box_shadow',
+ 'selector' => '{{WRAPPER}} .wpuf-form input[type="text"]:focus, {{WRAPPER}} .wpuf-form input[type="email"]:focus, {{WRAPPER}} .wpuf-form input[type="url"]:focus, {{WRAPPER}} .wpuf-form input[type="password"]:focus, {{WRAPPER}} .wpuf-form input[type="number"]:focus, {{WRAPPER}} .wpuf-form textarea:focus, {{WRAPPER}} .wpuf-form select:focus',
+ ]
+ );
+
+ $this->end_controls_tab();
+
+ $this->end_controls_tabs();
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register placeholder style controls.
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_placeholder_style_controls() {
+ $this->start_controls_section(
+ 'section_placeholder_style',
+ [
+ 'label' => __( 'Placeholder', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $placeholder_selector = '{{WRAPPER}} .wpuf-form input::placeholder, {{WRAPPER}} .wpuf-form textarea::placeholder, {{WRAPPER}} .wpuf-form input::-webkit-input-placeholder, {{WRAPPER}} .wpuf-form textarea::-webkit-input-placeholder, {{WRAPPER}} .wpuf-form input::-moz-placeholder, {{WRAPPER}} .wpuf-form textarea::-moz-placeholder, {{WRAPPER}} .wpuf-form input:-ms-input-placeholder, {{WRAPPER}} .wpuf-form textarea:-ms-input-placeholder';
+
+ $this->add_control(
+ 'placeholder_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [ $placeholder_selector => 'color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register radio and checkbox style controls.
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_radio_checkbox_style_controls() {
+ $this->start_controls_section(
+ 'section_radio_checkbox_style',
+ [
+ 'label' => __( 'Radio & Checkbox', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'radio_checkbox_size',
+ [
+ 'label' => __( 'Size', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px' ],
+ 'range' => [ 'px' => [ 'min' => 0, 'max' => 80, 'step' => 1 ] ],
+ 'default' => [ 'size' => 18, 'unit' => 'px' ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-form input[type="radio"], {{WRAPPER}} .wpuf-form input[type="checkbox"]' => 'width: {{SIZE}}{{UNIT}}; height: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'radio_checkbox_spacing',
+ [
+ 'label' => __( 'Spacing', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px', 'em' ],
+ 'range' => [ 'px' => [ 'min' => 0, 'max' => 30, 'step' => 1 ] ],
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-form input[type="radio"], {{WRAPPER}} .wpuf-form input[type="checkbox"]' => 'margin-right: {{SIZE}}{{UNIT}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'radio_checkbox_selector_color',
+ [
+ 'label' => __( 'Selector Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-form input[type="radio"], {{WRAPPER}} .wpuf-form input[type="checkbox"]' => 'accent-color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'radio_checkbox_options_text_color',
+ [
+ 'label' => __( 'Options Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [
+ '{{WRAPPER}} .wpuf-form .wpuf-radio-block, {{WRAPPER}} .wpuf-form .wpuf-checkbox-block, {{WRAPPER}} .wpuf-form .wpuf-radio-inline, {{WRAPPER}} .wpuf-form .wpuf-checkbox-inline' => 'color: {{VALUE}};',
+ ],
+ ]
+ );
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register upload button style controls
+ *
+ * Styles the file/image upload buttons (e.g. "Select File", "Select Image") within WPUF forms.
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_upload_button_style_controls() {
+ $btn_selector = '{{WRAPPER}} .wpuf-form .file-selector';
+ $align_selector = '{{WRAPPER}} .wpuf-form .wpuf-attachment-upload-filelist';
+
+ $this->start_controls_section(
+ 'section_upload_button_style',
+ [
+ 'label' => __( 'Upload Button', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_control(
+ 'upload_button_width_type',
+ [
+ 'label' => __( 'Width', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SELECT,
+ 'default' => 'custom',
+ 'options' => [
+ 'full-width' => __( 'Full Width', 'wp-user-frontend' ),
+ 'custom' => __( 'Custom', 'wp-user-frontend' ),
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'upload_button_align',
+ [
+ 'label' => __( 'Alignment', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::CHOOSE,
+ 'default' => 'left',
+ 'options' => [
+ 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-left' ],
+ 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-center' ],
+ 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-right' ],
+ ],
+ 'selectors' => [ $align_selector => 'text-align: {{VALUE}};' ],
+ 'condition' => [ 'upload_button_width_type' => 'custom' ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'upload_button_width',
+ [
+ 'label' => __( 'Width', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px', '%' ],
+ 'range' => [ 'px' => [ 'min' => 0, 'max' => 1200, 'step' => 1 ] ],
+ 'selectors' => [ $btn_selector => 'width: {{SIZE}}{{UNIT}};' ],
+ 'condition' => [ 'upload_button_width_type' => 'custom' ],
+ ]
+ );
+
+ $this->start_controls_tabs( 'tabs_upload_button_style' );
+
+ $this->start_controls_tab( 'tab_upload_button_normal', [ 'label' => __( 'Normal', 'wp-user-frontend' ) ] );
+
+ $this->add_control(
+ 'upload_button_bg_color',
+ [
+ 'label' => __( 'Background Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#6b7280',
+ 'selectors' => [ $btn_selector => 'background-color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->add_control(
+ 'upload_button_text_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#ffffff',
+ 'selectors' => [ $btn_selector => 'color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Typography::get_type(),
+ [
+ 'name' => 'upload_button_typography',
+ 'selector' => $btn_selector,
+ 'fields_options' => [
+ 'font_weight' => [
+ 'default' => '500',
+ ],
+ 'font_size' => [
+ 'default' => [
+ 'unit' => 'px',
+ 'size' => '16',
+ ],
+ ],
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Border::get_type(),
+ [
+ 'name' => 'upload_button_border',
+ 'selector' => $btn_selector,
+ 'fields_options' => [
+ 'border' => [
+ 'default' => 'solid',
+ ],
+ 'width' => [
+ 'default' => [
+ 'top' => '0',
+ 'right' => '0',
+ 'bottom' => '0',
+ 'left' => '0',
+ ],
+ ],
+ 'color' => [
+ 'default' => 'transparent',
+ ],
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'upload_button_border_radius',
+ [
+ 'label' => __( 'Border Radius', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', '%' ],
+ 'default' => [
+ 'top' => '6',
+ 'right' => '6',
+ 'bottom' => '6',
+ 'left' => '6',
+ 'unit' => 'px',
+ ],
+ 'selectors' => [ $btn_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'upload_button_padding',
+ [
+ 'label' => __( 'Padding', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'default' => [
+ 'top' => '12',
+ 'right' => '24',
+ 'bottom' => '12',
+ 'left' => '24',
+ 'unit' => 'px',
+ ],
+ 'selectors' => [ $btn_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Box_Shadow::get_type(),
+ [
+ 'name' => 'upload_button_box_shadow',
+ 'selector' => $btn_selector,
+ 'separator' => 'before',
+ 'fields_options' => [
+ 'box_shadow_type' => [
+ 'default' => 'yes',
+ ],
+ 'box_shadow' => [
+ 'default' => [
+ 'horizontal' => 0,
+ 'vertical' => 1,
+ 'blur' => 3,
+ 'spread' => 0,
+ 'color' => 'rgba(0, 0, 0, 0.1)',
+ ],
+ ],
+ ],
+ ]
+ );
+
+ $this->end_controls_tab();
+
+ $this->start_controls_tab( 'tab_upload_button_hover', [ 'label' => __( 'Hover', 'wp-user-frontend' ) ] );
+
+ $this->add_control(
+ 'upload_button_hover_bg_color',
+ [
+ 'label' => __( 'Background Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#4b5563',
+ 'selectors' => [ $btn_selector . ':hover' => 'background-color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->add_control(
+ 'upload_button_hover_text_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#ffffff',
+ 'selectors' => [ $btn_selector . ':hover' => 'color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->add_control(
+ 'upload_button_hover_border_color',
+ [
+ 'label' => __( 'Border Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [ $btn_selector . ':hover' => 'border-color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->end_controls_tab();
+
+ $this->end_controls_tabs();
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Register submit button style controls
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function register_submit_button_style_controls() {
+ $btn_selector = '{{WRAPPER}} .wpuf-form .wpuf-submit-button';
+
+ $this->start_controls_section(
+ 'section_submit_button_style',
+ [
+ 'label' => __( 'Submit Button', 'wp-user-frontend' ),
+ 'tab' => Controls_Manager::TAB_STYLE,
+ ]
+ );
+
+ $this->add_control(
+ 'submit_button_width_type',
+ [
+ 'label' => __( 'Width', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SELECT,
+ 'default' => 'custom',
+ 'options' => [
+ 'full-width' => __( 'Full Width', 'wp-user-frontend' ),
+ 'custom' => __( 'Custom', 'wp-user-frontend' ),
+ ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'submit_button_align',
+ [
+ 'label' => __( 'Alignment', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::CHOOSE,
+ 'default' => 'left',
+ 'options' => [
+ 'left' => [ 'title' => __( 'Left', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-left' ],
+ 'center' => [ 'title' => __( 'Center', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-center' ],
+ 'right' => [ 'title' => __( 'Right', 'wp-user-frontend' ), 'icon' => 'eicon-h-align-right' ],
+ ],
+ 'selectors' => [ '{{WRAPPER}} .wpuf-form .wpuf-submit' => 'text-align: {{VALUE}};' ],
+ 'condition' => [ 'submit_button_width_type' => 'custom' ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'submit_button_width',
+ [
+ 'label' => __( 'Width', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::SLIDER,
+ 'size_units' => [ 'px', '%' ],
+ 'range' => [ 'px' => [ 'min' => 0, 'max' => 1200, 'step' => 1 ] ],
+ 'selectors' => [ $btn_selector => 'width: {{SIZE}}{{UNIT}};' ],
+ 'condition' => [ 'submit_button_width_type' => 'custom' ],
+ ]
+ );
+
+ $this->start_controls_tabs( 'tabs_submit_button_style' );
+
+ $this->start_controls_tab( 'tab_submit_button_normal', [ 'label' => __( 'Normal', 'wp-user-frontend' ) ] );
+
+ $this->add_control(
+ 'submit_button_bg_color',
+ [
+ 'label' => __( 'Background Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#6b7280',
+ 'selectors' => [ $btn_selector => 'background-color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->add_control(
+ 'submit_button_text_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#ffffff',
+ 'selectors' => [ $btn_selector => 'color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Typography::get_type(),
+ [
+ 'name' => 'submit_button_typography',
+ 'selector' => $btn_selector,
+ 'fields_options' => [
+ 'font_weight' => [
+ 'default' => '500',
+ ],
+ 'font_size' => [
+ 'default' => [
+ 'unit' => 'px',
+ 'size' => '16',
+ ],
+ ],
+ ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Border::get_type(),
+ [
+ 'name' => 'submit_button_border',
+ 'selector' => $btn_selector,
+ 'fields_options' => [
+ 'border' => [
+ 'default' => 'solid',
+ ],
+ 'width' => [
+ 'default' => [
+ 'top' => '0',
+ 'right' => '0',
+ 'bottom' => '0',
+ 'left' => '0',
+ ],
+ ],
+ 'color' => [
+ 'default' => 'transparent',
+ ],
+ ],
+ ]
+ );
+
+ $this->add_control(
+ 'submit_button_border_radius',
+ [
+ 'label' => __( 'Border Radius', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', '%' ],
+ 'default' => [
+ 'top' => '6',
+ 'right' => '6',
+ 'bottom' => '6',
+ 'left' => '6',
+ 'unit' => 'px',
+ ],
+ 'selectors' => [ $btn_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
+ ]
+ );
+
+ $this->add_responsive_control(
+ 'submit_button_padding',
+ [
+ 'label' => __( 'Padding', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::DIMENSIONS,
+ 'size_units' => [ 'px', 'em', '%' ],
+ 'default' => [
+ 'top' => '12',
+ 'right' => '24',
+ 'bottom' => '12',
+ 'left' => '24',
+ 'unit' => 'px',
+ ],
+ 'selectors' => [ $btn_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
+ ]
+ );
+
+ $this->add_group_control(
+ Group_Control_Box_Shadow::get_type(),
+ [
+ 'name' => 'submit_button_box_shadow',
+ 'selector' => $btn_selector,
+ 'separator' => 'before',
+ 'fields_options' => [
+ 'box_shadow_type' => [
+ 'default' => 'yes',
+ ],
+ 'box_shadow' => [
+ 'default' => [
+ 'horizontal' => 0,
+ 'vertical' => 1,
+ 'blur' => 3,
+ 'spread' => 0,
+ 'color' => 'rgba(0, 0, 0, 0.1)',
+ ],
+ ],
+ ],
+ ]
+ );
+
+ $this->end_controls_tab();
+
+ $this->start_controls_tab( 'tab_submit_button_hover', [ 'label' => __( 'Hover', 'wp-user-frontend' ) ] );
+
+ $this->add_control(
+ 'submit_button_hover_bg_color',
+ [
+ 'label' => __( 'Background Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#4b5563',
+ 'selectors' => [ $btn_selector . ':hover' => 'background-color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->add_control(
+ 'submit_button_hover_text_color',
+ [
+ 'label' => __( 'Text Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'default' => '#ffffff',
+ 'selectors' => [ $btn_selector . ':hover' => 'color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->add_control(
+ 'submit_button_hover_border_color',
+ [
+ 'label' => __( 'Border Color', 'wp-user-frontend' ),
+ 'type' => Controls_Manager::COLOR,
+ 'selectors' => [ $btn_selector . ':hover' => 'border-color: {{VALUE}};' ],
+ ]
+ );
+
+ $this->end_controls_tab();
+
+ $this->end_controls_tabs();
+
+ $this->end_controls_section();
+ }
+
+ /**
+ * Render the widget output on the frontend
+ *
+ * @since WPUF_SINCE
+ *
+ * @return void
+ */
+ protected function render() {
+ $settings = $this->get_settings_for_display();
+ $form_id = isset( $settings['form_id'] ) ? $settings['form_id'] : null;
+
+ if ( empty( $form_id ) ) {
+ return;
+ }
+
+ $wrapper_classes = [ 'wpuf-elementor-widget-wrapper' ];
+
+ if ( ! empty( $settings['submit_button_width_type'] ) && 'full-width' === $settings['submit_button_width_type'] ) {
+ $wrapper_classes[] = 'wpuf-elementor-submit-full';
+ }
+
+ if ( ! empty( $settings['upload_button_width_type'] ) && 'full-width' === $settings['upload_button_width_type'] ) {
+ $wrapper_classes[] = 'wpuf-elementor-upload-full';
+ }
+
+ /**
+ * Filters the CSS classes applied to the widget wrapper.
+ *
+ * @since WPUF_SINCE
+ *
+ * @param string[] $wrapper_classes Array of class names.
+ * @param array $settings Widget settings.
+ * @param int|null $form_id Selected form ID.
+ */
+ $wrapper_classes = apply_filters( 'wpuf_elementor_widget_wrapper_classes', $wrapper_classes, $settings, $form_id );
+
+ $this->add_render_attribute( 'wrapper', 'class', $wrapper_classes );
+
+ // Set alignment attribute if not default
+ if ( ! empty( $settings['container_alignment'] ) && 'default' !== $settings['container_alignment'] ) {
+ $this->add_render_attribute( 'wrapper', 'data-align', $settings['container_alignment'] );
+ }
+
+ $wrapper_attributes = apply_filters( 'wpuf_elementor_widget_wrapper_attributes', [], $settings, $form_id );
+ foreach ( $wrapper_attributes as $attr_key => $attr_value ) {
+ if ( is_string( $attr_key ) && is_string( $attr_value ) ) {
+ $this->add_render_attribute( 'wrapper', $attr_key, $attr_value );
+ }
+ }
+
+ $shortcode_str = '[wpuf_form id="' . $form_id . '"]';
+ $output = do_shortcode( $shortcode_str );
+
+ $is_elementor = class_exists( '\Elementor\Plugin' ) && (
+ ( isset( \Elementor\Plugin::$instance->editor ) && \Elementor\Plugin::$instance->editor->is_edit_mode() )
+ || ( isset( \Elementor\Plugin::$instance->preview ) && \Elementor\Plugin::$instance->preview->is_preview_mode() )
+ );
+
+ echo 'get_render_attribute_string( 'wrapper' ) ) . '>';
+ echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- shortcode output
+
+ // Initialize TinyMCE in Elementor preview
+ if ( $is_elementor ) {
+ ?>
+
+ ';
+
+ /**
+ * Fires after the widget has rendered its output.
+ *
+ * @since WPUF_SINCE
+ *
+ * @param \Elementor\Widget_Base $this The widget instance.
+ */
+ do_action( 'wpuf_elementor_widget_after_render', $this );
+ }
+
+ /**
+ * Render the widget output in the editor.
+ *
+ * When empty, Elementor will fall back to using the render() method for
+ * both frontend and editor preview.
+ *
+ * @since WPUF_SINCE
+ *
+ * @access protected
+ */
+ protected function content_template() {}
+}
diff --git a/languages/wp-user-frontend.pot b/languages/wp-user-frontend.pot
index 5d72a6b4b..77270aba1 100644
--- a/languages/wp-user-frontend.pot
+++ b/languages/wp-user-frontend.pot
@@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WP User Frontend 4.2.8\n"
"Report-Msgid-Bugs-To: https://wedevs.com/contact/\n"
-"POT-Creation-Date: 2026-01-28 06:28:38+00:00\n"
+"POT-Creation-Date: 2026-02-17 06:00:07+00:00\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -219,6 +219,7 @@ msgid "WP User Frontend"
msgstr ""
#: admin/class-admin-settings.php:89 includes/Admin/Menu.php:24
+#: includes/Integrations/Elementor/Elementor.php:240
msgid "User Frontend"
msgstr ""
@@ -600,26 +601,26 @@ msgstr ""
msgid "Learn More"
msgstr ""
-#: admin/html/form-settings-display.php:11 wpuf-functions.php:5603
+#: admin/html/form-settings-display.php:11 wpuf-functions.php:5608
msgid "Label Position"
msgstr ""
-#: admin/html/form-settings-display.php:16 wpuf-functions.php:5606
+#: admin/html/form-settings-display.php:16 wpuf-functions.php:5611
msgid "Above Element"
msgstr ""
-#: admin/html/form-settings-display.php:17 wpuf-functions.php:5607
+#: admin/html/form-settings-display.php:17 wpuf-functions.php:5612
msgid "Left of Element"
msgstr ""
-#: admin/html/form-settings-display.php:18 wpuf-functions.php:5608
+#: admin/html/form-settings-display.php:18 wpuf-functions.php:5613
msgid "Right of Element"
msgstr ""
#: admin/html/form-settings-display.php:19
#: includes/Admin/Customizer_Options.php:119
#: includes/Fields/Field_Contract.php:400
-#: includes/Fields/Form_Field_Column.php:112 wpuf-functions.php:5609
+#: includes/Fields/Form_Field_Column.php:112 wpuf-functions.php:5614
msgid "Hidden"
msgstr ""
@@ -627,7 +628,7 @@ msgstr ""
msgid "Where the labels of the form should display"
msgstr ""
-#: admin/html/form-settings-display.php:35 wpuf-functions.php:5596
+#: admin/html/form-settings-display.php:35 wpuf-functions.php:5601
msgid "Use Theme CSS"
msgstr ""
@@ -642,7 +643,8 @@ msgstr ""
#: includes/Fields/Field_Contract.php:519
#: includes/Fields/Form_Field_Checkbox.php:86
#: includes/Fields/Form_Field_Radio.php:86 includes/Free/Form_Element.php:525
-#: includes/Frontend.php:122 includes/functions/settings-options.php:128
+#: includes/Frontend.php:122 includes/Integrations/Elementor/Elementor.php:171
+#: includes/functions/settings-options.php:128
#: includes/functions/settings-options.php:147
#: includes/functions/settings-options.php:268
#: includes/functions/settings-options.php:279
@@ -660,7 +662,8 @@ msgstr ""
#: includes/Fields/Field_Contract.php:518
#: includes/Fields/Form_Field_Checkbox.php:85
#: includes/Fields/Form_Field_Radio.php:85 includes/Free/Form_Element.php:524
-#: includes/Frontend.php:121 includes/functions/settings-options.php:127
+#: includes/Frontend.php:121 includes/Integrations/Elementor/Elementor.php:170
+#: includes/functions/settings-options.php:127
#: includes/functions/settings-options.php:146
#: includes/functions/settings-options.php:267
#: includes/functions/settings-options.php:278
@@ -680,7 +683,7 @@ msgid "Payment Options"
msgstr ""
#: admin/html/form-settings-payment.php:26 includes/Setup_Wizard.php:339
-#: includes/functions/settings-options.php:564 wpuf-functions.php:5477
+#: includes/functions/settings-options.php:564 wpuf-functions.php:5482
msgid "Enable Payments"
msgstr ""
@@ -745,7 +748,7 @@ msgid "Amount to be charged per post"
msgstr ""
#: admin/html/form-settings-payment.php:88
-#: includes/functions/settings-options.php:650 wpuf-functions.php:5512
+#: includes/functions/settings-options.php:650 wpuf-functions.php:5517
msgid "Payment Success Page"
msgstr ""
@@ -767,7 +770,7 @@ msgstr ""
msgid "Set Post Status to"
msgstr ""
-#: admin/html/form-settings-post-edit.php:24 wpuf-functions.php:5335
+#: admin/html/form-settings-post-edit.php:24 wpuf-functions.php:5340
msgid "No Change"
msgstr ""
@@ -777,7 +780,7 @@ msgid "Redirect To"
msgstr ""
#: admin/html/form-settings-post-edit.php:36
-#: admin/html/form-settings-post.php:138 wpuf-functions.php:5263
+#: admin/html/form-settings-post.php:138 wpuf-functions.php:5268
msgid "Newly created post"
msgstr ""
@@ -788,13 +791,13 @@ msgstr ""
#: admin/html/form-settings-post-edit.php:38
#: admin/html/form-settings-post.php:140 includes/Free/Form_Element.php:422
-#: wpuf-functions.php:5265 wpuf-functions.php:5350
+#: wpuf-functions.php:5270 wpuf-functions.php:5355
msgid "To a page"
msgstr ""
#: admin/html/form-settings-post-edit.php:39
#: admin/html/form-settings-post.php:141 includes/Free/Form_Element.php:423
-#: wpuf-functions.php:5266 wpuf-functions.php:5351
+#: wpuf-functions.php:5271 wpuf-functions.php:5356
msgid "To a custom URL"
msgstr ""
@@ -802,19 +805,19 @@ msgstr ""
msgid "After successfull submit, where the page will redirect to"
msgstr ""
-#: admin/html/form-settings-post-edit.php:54 wpuf-functions.php:5355
+#: admin/html/form-settings-post-edit.php:54 wpuf-functions.php:5360
msgid "Post Update Message"
msgstr ""
#: admin/html/form-settings-post-edit.php:61
#: admin/html/form-settings-post.php:163 includes/Free/Form_Element.php:452
-#: wpuf-functions.php:5275 wpuf-functions.php:5369
+#: wpuf-functions.php:5280 wpuf-functions.php:5374
msgid "Page"
msgstr ""
#: admin/html/form-settings-post-edit.php:76
#: admin/html/form-settings-post.php:178 includes/Free/Form_Element.php:475
-#: wpuf-functions.php:5281 wpuf-functions.php:5375
+#: wpuf-functions.php:5286 wpuf-functions.php:5380
msgid "Custom URL"
msgstr ""
@@ -844,7 +847,7 @@ msgstr ""
msgid "This page is restricted. Please {login} / {register} to view this page."
msgstr ""
-#: admin/html/form-settings-post.php:15 wpuf-functions.php:5272
+#: admin/html/form-settings-post.php:15 wpuf-functions.php:5277
msgid "Post saved"
msgstr ""
@@ -859,7 +862,7 @@ msgstr ""
msgid "Save Draft"
msgstr ""
-#: admin/html/form-settings-post.php:29 wpuf-functions.php:5236
+#: admin/html/form-settings-post.php:29 wpuf-functions.php:5241
msgid "Post Type"
msgstr ""
@@ -901,7 +904,7 @@ msgstr ""
msgid "After successful submit, where the page will redirect to"
msgstr ""
-#: admin/html/form-settings-post.php:156 wpuf-functions.php:5270
+#: admin/html/form-settings-post.php:156 wpuf-functions.php:5275
msgid "Message to show"
msgstr ""
@@ -909,11 +912,11 @@ msgstr ""
msgid "Comment Status"
msgstr ""
-#: admin/html/form-settings-post.php:188 wpuf-functions.php:5627
+#: admin/html/form-settings-post.php:188 wpuf-functions.php:5632
msgid "Open"
msgstr ""
-#: admin/html/form-settings-post.php:189 wpuf-functions.php:5628
+#: admin/html/form-settings-post.php:189 wpuf-functions.php:5633
msgid "Closed"
msgstr ""
@@ -947,7 +950,7 @@ msgstr ""
msgid "Email"
msgstr ""
-#: admin/html/form-submission-restriction.php:29 wpuf-functions.php:5409
+#: admin/html/form-submission-restriction.php:29 wpuf-functions.php:5414
msgid "Guest Post"
msgstr ""
@@ -967,7 +970,7 @@ msgstr ""
msgid "User Details"
msgstr ""
-#: admin/html/form-submission-restriction.php:46 wpuf-functions.php:5418
+#: admin/html/form-submission-restriction.php:46 wpuf-functions.php:5423
msgid "Require Name and Email address"
msgstr ""
@@ -977,7 +980,7 @@ msgid ""
"name and email address"
msgstr ""
-#: admin/html/form-submission-restriction.php:53 wpuf-functions.php:5428
+#: admin/html/form-submission-restriction.php:53 wpuf-functions.php:5433
msgid "Name Label"
msgstr ""
@@ -985,7 +988,7 @@ msgstr ""
msgid "Label text for name field"
msgstr ""
-#: admin/html/form-submission-restriction.php:63 wpuf-functions.php:5436
+#: admin/html/form-submission-restriction.php:63 wpuf-functions.php:5441
msgid "E-Mail Label"
msgstr ""
@@ -1026,7 +1029,7 @@ msgid "Choose which roles can submit posts."
msgstr ""
#: admin/html/form-submission-restriction.php:117
-#: includes/functions/settings-options.php:338 wpuf-functions.php:5460
+#: includes/functions/settings-options.php:338 wpuf-functions.php:5465
msgid "Unauthorized Message"
msgstr ""
@@ -1052,16 +1055,16 @@ msgstr ""
msgid "Schedule Period"
msgstr ""
-#: admin/html/form-submission-restriction.php:140 wpuf-functions.php:5641
+#: admin/html/form-submission-restriction.php:140 wpuf-functions.php:5646
msgid "From"
msgstr ""
-#: admin/html/form-submission-restriction.php:151 wpuf-functions.php:5651
+#: admin/html/form-submission-restriction.php:151 wpuf-functions.php:5656
msgid "Form Pending Message"
msgstr ""
#: admin/html/form-submission-restriction.php:158
-#: includes/Free/Free_Loader.php:1778 wpuf-functions.php:5655
+#: includes/Free/Free_Loader.php:1778 wpuf-functions.php:5660
msgid "Form Expired Message"
msgstr ""
@@ -1077,11 +1080,11 @@ msgstr ""
msgid "Limit the number of entries allowed for this form"
msgstr ""
-#: admin/html/form-submission-restriction.php:180 wpuf-functions.php:5664
+#: admin/html/form-submission-restriction.php:180 wpuf-functions.php:5669
msgid "Number of Entries"
msgstr ""
-#: admin/html/form-submission-restriction.php:187 wpuf-functions.php:5669
+#: admin/html/form-submission-restriction.php:187 wpuf-functions.php:5674
msgid "Limit Reached Message"
msgstr ""
@@ -1110,7 +1113,7 @@ msgstr ""
#: admin/installer.php:84 includes/Admin/Admin_Installer.php:86
#: includes/Admin/Shortcodes_Button.php:85
-#: includes/functions/settings-options.php:24 wpuf-functions.php:2292
+#: includes/functions/settings-options.php:24 wpuf-functions.php:2297
msgid "Dashboard"
msgstr ""
@@ -1140,7 +1143,7 @@ msgstr ""
#: includes/Admin/Shortcodes_Button.php:105 includes/Admin/Subscription.php:485
#: includes/Admin/Subscription.php:504 includes/Admin/Subscription.php:505
#: includes/Admin/Subscription.php:506 templates/dashboard/subscription.php:169
-#: wpuf-functions.php:2273
+#: wpuf-functions.php:2278
msgid "Subscription"
msgstr ""
@@ -1189,39 +1192,46 @@ msgstr ""
#: admin/posting.php:74 class/render-form.php:1703
#: includes/Admin/Posting.php:130 includes/Admin.php:172
-#: includes/Fields/Field_Contract.php:996 includes/Frontend.php:81
+#: includes/Fields/Field_Contract.php:1023 includes/Frontend.php:81
+#: includes/Integrations/Elementor/Elementor.php:134
#: includes/Render_Form.php:1594
msgid "Are you sure?"
msgstr ""
#: admin/posting.php:75 includes/Admin/Forms/Admin_Form_Builder.php:342
#: includes/Admin/Posting.php:131 includes/Admin.php:173
-#: includes/Fields/Field_Contract.php:997 includes/Frontend.php:82
+#: includes/Fields/Field_Contract.php:1024 includes/Frontend.php:82
+#: includes/Integrations/Elementor/Elementor.php:135
msgid "Yes, delete it"
msgstr ""
#: admin/posting.php:76 includes/Admin/Posting.php:132 includes/Admin.php:174
-#: includes/Fields/Field_Contract.php:998 includes/Frontend.php:83
+#: includes/Fields/Field_Contract.php:1025 includes/Frontend.php:83
+#: includes/Integrations/Elementor/Elementor.php:136
msgid "No, cancel it"
msgstr ""
#: admin/posting.php:82 includes/Admin/Posting.php:138 includes/Admin.php:182
-#: includes/Fields/Field_Contract.php:1008 includes/Frontend.php:93
+#: includes/Fields/Field_Contract.php:1035 includes/Frontend.php:93
+#: includes/Integrations/Elementor/Elementor.php:144
msgid "Allowed Files"
msgstr ""
#: admin/posting.php:85 includes/Admin/Posting.php:141 includes/Admin.php:188
-#: includes/Fields/Field_Contract.php:1014 includes/Frontend.php:99
+#: includes/Fields/Field_Contract.php:1041 includes/Frontend.php:99
+#: includes/Integrations/Elementor/Elementor.php:150
msgid "Maximum number of files reached!"
msgstr ""
#: admin/posting.php:86 includes/Admin/Posting.php:142 includes/Admin.php:189
-#: includes/Fields/Field_Contract.php:1015 includes/Frontend.php:100
+#: includes/Fields/Field_Contract.php:1042 includes/Frontend.php:100
+#: includes/Integrations/Elementor/Elementor.php:151
msgid "The file you have uploaded exceeds the file size limit. Please try again."
msgstr ""
#: admin/posting.php:87 includes/Admin/Posting.php:143 includes/Admin.php:190
-#: includes/Fields/Field_Contract.php:1019 includes/Frontend.php:104
+#: includes/Fields/Field_Contract.php:1046 includes/Frontend.php:104
+#: includes/Integrations/Elementor/Elementor.php:152
msgid "You have uploaded an incorrect file type. Please try again."
msgstr ""
@@ -1293,12 +1303,12 @@ msgid "Unauthorized operation"
msgstr ""
#: admin/template-post.php:36 includes/Admin/Forms/Template_Post.php:39
-#: includes/Fields/Form_Field_Post_Content.php:167
+#: includes/Fields/Form_Field_Post_Content.php:169
msgid "Enable Image Insertion"
msgstr ""
#: admin/template-post.php:42 includes/Admin/Forms/Template_Post.php:49
-#: includes/Fields/Form_Field_Post_Content.php:169
+#: includes/Fields/Form_Field_Post_Content.php:171
msgid "Enable image upload in post area"
msgstr ""
@@ -1568,6 +1578,7 @@ msgstr ""
#: admin/template.php:127 includes/Admin/Forms/Admin_Template.php:146
#: includes/Fields/Field_Contract.php:652
+#: includes/Integrations/Elementor/Widget.php:560
msgid "Size"
msgstr ""
@@ -1608,6 +1619,9 @@ msgstr ""
#: admin/template.php:188 includes/Admin/Forms/Admin_Template.php:217
#: includes/Fields/Field_Contract.php:740
+#: includes/Integrations/Elementor/Widget.php:414
+#: includes/Integrations/Elementor/Widget.php:673
+#: includes/Integrations/Elementor/Widget.php:896
msgid "Normal"
msgstr ""
@@ -2047,8 +2061,8 @@ msgstr ""
#: includes/Integrations/WPUF_ACF_Compatibility.php:90
#: includes/Integrations/WPUF_ACF_Compatibility.php:156
#: includes/Widgets/Login_Widget.php:36 includes/Widgets/Login_Widget.php:62
-#: includes/Widgets/Login_Widget.php:79 wpuf-functions.php:1716
-#: wpuf-functions.php:1989
+#: includes/Widgets/Login_Widget.php:79 wpuf-functions.php:1721
+#: wpuf-functions.php:1994
msgid "Permission denied"
msgstr ""
@@ -2244,7 +2258,7 @@ msgstr ""
#: includes/Admin/Admin_Subscription.php:436
#: includes/Admin/Admin_Subscription.php:1053
-#: includes/Admin/views/support.php:77 wpuf-functions.php:5121
+#: includes/Admin/views/support.php:77 wpuf-functions.php:5126
msgid "Payment Settings"
msgstr ""
@@ -2283,7 +2297,7 @@ msgstr ""
#: includes/Admin/Admin_Subscription.php:532
#: includes/Admin/Admin_Subscription.php:1085 includes/Free/Form_Element.php:59
-#: wpuf-functions.php:5147
+#: wpuf-functions.php:5152
msgid "Post Expiration"
msgstr ""
@@ -2410,8 +2424,8 @@ msgid "Select Package:"
msgstr ""
#: includes/Admin/Admin_Subscription.php:950
-#: includes/functions/settings-options.php:811 wpuf-functions.php:2041
-#: wpuf-functions.php:2309
+#: includes/functions/settings-options.php:811 wpuf-functions.php:2046
+#: wpuf-functions.php:2314
msgid "— Select —"
msgstr ""
@@ -2558,12 +2572,12 @@ msgid "Publish"
msgstr ""
#: includes/Admin/Admin_Subscription.php:1284 wpuf-functions.php:68
-#: wpuf-functions.php:5288 wpuf-functions.php:5331
+#: wpuf-functions.php:5293 wpuf-functions.php:5336
msgid "Draft"
msgstr ""
-#: includes/Admin/Admin_Subscription.php:1285 wpuf-functions.php:5289
-#: wpuf-functions.php:5332
+#: includes/Admin/Admin_Subscription.php:1285 wpuf-functions.php:5294
+#: wpuf-functions.php:5337
msgid "Pending Review"
msgstr ""
@@ -2741,8 +2755,8 @@ msgstr ""
#: includes/Admin/Admin_Tools.php:55 includes/Admin/Admin_Tools.php:118
#: includes/Admin/List_Table_Subscribers.php:170
-#: includes/Admin/List_Table_Transactions.php:97 wpuf-functions.php:3744
-#: wpuf-functions.php:5722
+#: includes/Admin/List_Table_Transactions.php:97 wpuf-functions.php:3749
+#: wpuf-functions.php:5727
msgid "All"
msgstr ""
@@ -2908,7 +2922,7 @@ msgid "Customize WPUF Settings"
msgstr ""
#: includes/Admin/Customizer_Options.php:75 includes/Frontend/Payment.php:157
-#: wpuf-functions.php:2274
+#: wpuf-functions.php:2279
msgid "Billing Address"
msgstr ""
@@ -3193,7 +3207,7 @@ msgid "— No Template —"
msgstr ""
#: includes/Admin/Forms/Post/Templates/Form_Template.php:231
-#: includes/Free/Free_Loader.php:1706 wpuf-functions.php:5312
+#: includes/Free/Free_Loader.php:1706 wpuf-functions.php:5317
msgid ""
"If selected a form template, it will try to execute that integration "
"options when new post created and updated."
@@ -3204,7 +3218,7 @@ msgstr ""
#: includes/Admin/views/shortcode-builder.php:8
#: includes/Free/Free_Loader.php:1712 includes/Free/Free_Loader.php:1716
#: includes/Free/Free_Loader.php:1720 includes/Free/Free_Loader.php:1724
-#: includes/Free/Free_Loader.php:1728 wpuf-functions.php:5195
+#: includes/Free/Free_Loader.php:1728 wpuf-functions.php:5200
msgid "Post Form"
msgstr ""
@@ -4739,6 +4753,7 @@ msgid "Try Again"
msgstr ""
#: includes/Ajax/Address_Form_Ajax.php:40 includes/Frontend.php:178
+#: includes/Integrations/Elementor/Elementor.php:217
msgid "Some Required Fields are not filled!"
msgstr ""
@@ -5613,7 +5628,7 @@ msgstr ""
msgid "Choose how you want the progressbar"
msgstr ""
-#: includes/Free/Form_Element.php:227 wpuf-functions.php:5546
+#: includes/Free/Form_Element.php:227 wpuf-functions.php:5551
msgid "New post created"
msgstr ""
@@ -5621,8 +5636,8 @@ msgstr ""
msgid "A post has been edited"
msgstr ""
-#: includes/Free/Form_Element.php:236 wpuf-functions.php:5525
-#: wpuf-functions.php:5532
+#: includes/Free/Form_Element.php:236 wpuf-functions.php:5530
+#: wpuf-functions.php:5537
msgid "New Post Notification"
msgstr ""
@@ -5639,13 +5654,13 @@ msgid "Learn more about Email Notification"
msgstr ""
#: includes/Free/Form_Element.php:255 includes/Free/Form_Element.php:292
-#: includes/Free/Free_Loader.php:1636 wpuf-functions.php:5538
-#: wpuf-functions.php:5645
+#: includes/Free/Free_Loader.php:1636 wpuf-functions.php:5543
+#: wpuf-functions.php:5650
msgid "To"
msgstr ""
#: includes/Free/Form_Element.php:262 includes/Free/Form_Element.php:297
-#: includes/Free/Free_Loader.php:1641 wpuf-functions.php:5544
+#: includes/Free/Free_Loader.php:1641 wpuf-functions.php:5549
msgid "Subject"
msgstr ""
@@ -5653,7 +5668,7 @@ msgstr ""
msgid "Message"
msgstr ""
-#: includes/Free/Form_Element.php:274 wpuf-functions.php:5574
+#: includes/Free/Form_Element.php:274 wpuf-functions.php:5579
msgid "Update Post Notification"
msgstr ""
@@ -5757,7 +5772,7 @@ msgid ""
msgstr ""
#: includes/Free/Free_Loader.php:285 templates/account.php:41
-#: wpuf-functions.php:2272
+#: wpuf-functions.php:2277
msgid "Edit Profile"
msgstr ""
@@ -6277,6 +6292,12 @@ msgid "Background color for progressbar or active step."
msgstr ""
#: includes/Free/Free_Loader.php:1609
+#: includes/Integrations/Elementor/Widget.php:419
+#: includes/Integrations/Elementor/Widget.php:480
+#: includes/Integrations/Elementor/Widget.php:678
+#: includes/Integrations/Elementor/Widget.php:802
+#: includes/Integrations/Elementor/Widget.php:901
+#: includes/Integrations/Elementor/Widget.php:1025
msgid "Background Color"
msgstr ""
@@ -6288,7 +6309,7 @@ msgstr ""
msgid "Enable Update Post Notification"
msgstr ""
-#: includes/Free/Free_Loader.php:1646 wpuf-functions.php:5550
+#: includes/Free/Free_Loader.php:1646 wpuf-functions.php:5555
msgid "Email Body"
msgstr ""
@@ -6296,7 +6317,7 @@ msgstr ""
msgid "Conditional Logic on Submit"
msgstr ""
-#: includes/Free/Free_Loader.php:1704 wpuf-functions.php:5589
+#: includes/Free/Free_Loader.php:1704 wpuf-functions.php:5594
msgid "Choose Form Style"
msgstr ""
@@ -7017,86 +7038,86 @@ msgstr ""
msgid "Subscription Page settings not set in admin settings"
msgstr ""
-#: includes/Frontend.php:115
+#: includes/Frontend.php:115 includes/Integrations/Elementor/Elementor.php:166
msgid "Please fix the errors to proceed"
msgstr ""
-#: includes/Frontend.php:117
+#: includes/Frontend.php:117 includes/Integrations/Elementor/Elementor.php:168
msgid "Word limit reached"
msgstr ""
-#: includes/Frontend.php:118
+#: includes/Frontend.php:118 includes/Integrations/Elementor/Elementor.php:169
msgid "Are you sure you want to cancel your current subscription ?"
msgstr ""
-#: includes/Frontend.php:123
+#: includes/Frontend.php:123 includes/Integrations/Elementor/Elementor.php:172
msgid "Maximum word limit reached. Please shorten your texts."
msgstr ""
-#: includes/Frontend.php:126
+#: includes/Frontend.php:126 includes/Integrations/Elementor/Elementor.php:173
msgid ""
"This field supports a maximum of %number% words, and the limit is reached. "
"Remove a few words to reach the acceptable limit of the field."
msgstr ""
-#: includes/Frontend.php:130
+#: includes/Frontend.php:130 includes/Integrations/Elementor/Elementor.php:174
msgid "Minimum word required."
msgstr ""
-#: includes/Frontend.php:131
+#: includes/Frontend.php:131 includes/Integrations/Elementor/Elementor.php:175
msgid "This field requires minimum %number% words. Please add some more text."
msgstr ""
-#: includes/Frontend.php:134
+#: includes/Frontend.php:134 includes/Integrations/Elementor/Elementor.php:176
msgid "Maximum character limit reached. Please shorten your texts."
msgstr ""
-#: includes/Frontend.php:137
+#: includes/Frontend.php:137 includes/Integrations/Elementor/Elementor.php:177
msgid ""
"This field supports a maximum of %number% characters, and the limit is "
"reached. Remove a few characters to reach the acceptable limit of the field."
msgstr ""
-#: includes/Frontend.php:141
+#: includes/Frontend.php:141 includes/Integrations/Elementor/Elementor.php:178
msgid "Minimum character required."
msgstr ""
-#: includes/Frontend.php:142
+#: includes/Frontend.php:142 includes/Integrations/Elementor/Elementor.php:179
msgid ""
"This field requires minimum %number% characters. Please add some more "
"character."
msgstr ""
-#: includes/Frontend.php:148
+#: includes/Frontend.php:148 includes/Integrations/Elementor/Elementor.php:181
#. translators: %shortcode% is the shortcode name
msgid "Using %shortcode% is restricted"
msgstr ""
-#: includes/Frontend.php:149
+#: includes/Frontend.php:149 includes/Integrations/Elementor/Elementor.php:182
msgid "Your password should be at least weak in strength"
msgstr ""
-#: includes/Frontend.php:150
+#: includes/Frontend.php:150 includes/Integrations/Elementor/Elementor.php:183
msgid "Your password needs to be medium strength for better protection"
msgstr ""
-#: includes/Frontend.php:151
+#: includes/Frontend.php:151 includes/Integrations/Elementor/Elementor.php:184
msgid "Create a strong password for maximum security"
msgstr ""
-#: includes/Frontend.php:157
+#: includes/Frontend.php:157 includes/Integrations/Elementor/Elementor.php:193
msgid "is required"
msgstr ""
-#: includes/Frontend.php:158
+#: includes/Frontend.php:158 includes/Integrations/Elementor/Elementor.php:194
msgid "does not match"
msgstr ""
-#: includes/Frontend.php:159
+#: includes/Frontend.php:159 includes/Integrations/Elementor/Elementor.php:195
msgid "is not valid"
msgstr ""
-#: includes/Frontend.php:168
+#: includes/Frontend.php:168 includes/Integrations/Elementor/Elementor.php:206
msgid "Please Cancel Your Currently Active Pack first!"
msgstr ""
@@ -7117,6 +7138,172 @@ msgstr ""
msgid "Mark the %1$s as featured (remaining %2$d)"
msgstr ""
+#: includes/Integrations/Elementor/Widget.php:42
+msgid "User Frontend Form"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:120
+msgid "Content"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:127
+msgid "Select Form"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:171
+msgid "Select a Form"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:201
+msgid "Form Container"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:210
+msgid "Background"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:219
+msgid "Max Width"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:235
+#: includes/Integrations/Elementor/Widget.php:401
+#: includes/Integrations/Elementor/Widget.php:646
+#: includes/Integrations/Elementor/Widget.php:869
+msgid "Alignment"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:239
+#: includes/functions/settings-options.php:116
+msgid "Default"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:243
+#: includes/Integrations/Elementor/Widget.php:404
+#: includes/Integrations/Elementor/Widget.php:650
+#: includes/Integrations/Elementor/Widget.php:873
+#: includes/functions/settings-options.php:595
+msgid "Left"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:247
+#: includes/Integrations/Elementor/Widget.php:405
+#: includes/Integrations/Elementor/Widget.php:651
+#: includes/Integrations/Elementor/Widget.php:874
+msgid "Center"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:251
+#: includes/Integrations/Elementor/Widget.php:406
+#: includes/Integrations/Elementor/Widget.php:652
+#: includes/Integrations/Elementor/Widget.php:875
+#: includes/functions/settings-options.php:597
+msgid "Right"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:262
+#: includes/Integrations/Elementor/Widget.php:457
+#: includes/Integrations/Elementor/Widget.php:758
+#: includes/Integrations/Elementor/Widget.php:981
+msgid "Padding"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:274
+msgid "Margin"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:294
+#: includes/Integrations/Elementor/Widget.php:447
+#: includes/Integrations/Elementor/Widget.php:741
+#: includes/Integrations/Elementor/Widget.php:964
+msgid "Border Radius"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:325
+msgid "Labels"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:333
+#: includes/Integrations/Elementor/Widget.php:428
+#: includes/Integrations/Elementor/Widget.php:532
+#: includes/Integrations/Elementor/Widget.php:688
+#: includes/Integrations/Elementor/Widget.php:812
+#: includes/Integrations/Elementor/Widget.php:911
+#: includes/Integrations/Elementor/Widget.php:1035
+msgid "Text Color"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:352
+msgid "Asterisk Color"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:364
+msgid "Asterisk Size"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:393
+msgid "Input & Textarea"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:475
+msgid "Focus"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:522
+msgid "Placeholder"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:552
+msgid "Radio & Checkbox"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:574
+msgid "Spacing"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:587
+msgid "Selector Color"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:598
+msgid "Options Text Color"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:625
+msgid "Upload Button"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:633
+#: includes/Integrations/Elementor/Widget.php:662
+#: includes/Integrations/Elementor/Widget.php:856
+#: includes/Integrations/Elementor/Widget.php:885
+msgid "Width"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:637
+#: includes/Integrations/Elementor/Widget.php:860
+msgid "Full Width"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:638
+#: includes/Integrations/Elementor/Widget.php:861
+msgid "Custom"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:797
+#: includes/Integrations/Elementor/Widget.php:1020
+msgid "Hover"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:822
+#: includes/Integrations/Elementor/Widget.php:1045
+msgid "Border Color"
+msgstr ""
+
+#: includes/Integrations/Elementor/Widget.php:848
+msgid "Submit Button"
+msgstr ""
+
#: includes/Integrations/Events_Calendar/Templates/Event_Form_Template.php:23
msgid "The Events Calendar"
msgstr ""
@@ -7414,7 +7601,7 @@ msgstr ""
msgid "Select the authentication type for the N8N integration."
msgstr ""
-#: includes/Integrations/WPUF_N8N_Integration.php:193 wpuf-functions.php:3745
+#: includes/Integrations/WPUF_N8N_Integration.php:193 wpuf-functions.php:3750
msgid "None"
msgstr ""
@@ -8165,10 +8352,6 @@ msgstr ""
msgid "Admins, Editors, Authors, Contributors"
msgstr ""
-#: includes/functions/settings-options.php:116
-msgid "Default"
-msgstr ""
-
#: includes/functions/settings-options.php:121
msgid "Override the post edit link"
msgstr ""
@@ -8580,14 +8763,6 @@ msgstr ""
msgid "Currency Position"
msgstr ""
-#: includes/functions/settings-options.php:595
-msgid "Left"
-msgstr ""
-
-#: includes/functions/settings-options.php:597
-msgid "Right"
-msgstr ""
-
#: includes/functions/settings-options.php:599
msgid "Left with space"
msgstr ""
@@ -9353,11 +9528,11 @@ msgstr ""
msgid "Scheduled"
msgstr ""
-#: wpuf-functions.php:44 wpuf-functions.php:5290 wpuf-functions.php:5333
+#: wpuf-functions.php:44 wpuf-functions.php:5295 wpuf-functions.php:5338
msgid "Private"
msgstr ""
-#: wpuf-functions.php:65 wpuf-functions.php:5291 wpuf-functions.php:5334
+#: wpuf-functions.php:65 wpuf-functions.php:5296 wpuf-functions.php:5339
msgid "Published"
msgstr ""
@@ -9393,552 +9568,552 @@ msgstr ""
msgid "Directions »"
msgstr ""
-#: wpuf-functions.php:2543
+#: wpuf-functions.php:2548
msgid "United Arab Emirates Dirham"
msgstr ""
-#: wpuf-functions.php:2548
+#: wpuf-functions.php:2553
msgid "Australian Dollars"
msgstr ""
-#: wpuf-functions.php:2553
+#: wpuf-functions.php:2558
msgid "Argentine Peso"
msgstr ""
-#: wpuf-functions.php:2558
+#: wpuf-functions.php:2563
msgid "Bangladeshi Taka"
msgstr ""
-#: wpuf-functions.php:2563
+#: wpuf-functions.php:2568
msgid "Brazilian Real"
msgstr ""
-#: wpuf-functions.php:2568
+#: wpuf-functions.php:2573
msgid "Bulgarian Lev"
msgstr ""
-#: wpuf-functions.php:2573
+#: wpuf-functions.php:2578
msgid "Canadian Dollars"
msgstr ""
-#: wpuf-functions.php:2578
+#: wpuf-functions.php:2583
msgid "Chilean Peso"
msgstr ""
-#: wpuf-functions.php:2583
+#: wpuf-functions.php:2588
msgid "Chinese Yuan"
msgstr ""
-#: wpuf-functions.php:2588
+#: wpuf-functions.php:2593
msgid "Colombian Peso"
msgstr ""
-#: wpuf-functions.php:2593
+#: wpuf-functions.php:2598
msgid "Czech Koruna"
msgstr ""
-#: wpuf-functions.php:2598
+#: wpuf-functions.php:2603
msgid "Danish Krone"
msgstr ""
-#: wpuf-functions.php:2603
+#: wpuf-functions.php:2608
msgid "Dominican Peso"
msgstr ""
-#: wpuf-functions.php:2608
+#: wpuf-functions.php:2613
msgid "Algerian Dinar"
msgstr ""
-#: wpuf-functions.php:2613
+#: wpuf-functions.php:2618
msgid "Euros"
msgstr ""
-#: wpuf-functions.php:2618
+#: wpuf-functions.php:2623
msgid "Hong Kong Dollar"
msgstr ""
-#: wpuf-functions.php:2623
+#: wpuf-functions.php:2628
msgid "Croatia kuna"
msgstr ""
-#: wpuf-functions.php:2628
+#: wpuf-functions.php:2633
msgid "Hungarian Forint"
msgstr ""
-#: wpuf-functions.php:2633
+#: wpuf-functions.php:2638
msgid "Icelandic krona"
msgstr ""
-#: wpuf-functions.php:2638
+#: wpuf-functions.php:2643
msgid "Indonesia Rupiah"
msgstr ""
-#: wpuf-functions.php:2643
+#: wpuf-functions.php:2648
msgid "Indian Rupee"
msgstr ""
-#: wpuf-functions.php:2648
+#: wpuf-functions.php:2653
msgid "Mauritian Rupee"
msgstr ""
-#: wpuf-functions.php:2653
+#: wpuf-functions.php:2658
msgid "Nepali Rupee"
msgstr ""
-#: wpuf-functions.php:2658
+#: wpuf-functions.php:2663
msgid "Israeli Shekel"
msgstr ""
-#: wpuf-functions.php:2663
+#: wpuf-functions.php:2668
msgid "Japanese Yen"
msgstr ""
-#: wpuf-functions.php:2668
+#: wpuf-functions.php:2673
msgid "Lao Kip"
msgstr ""
-#: wpuf-functions.php:2673
+#: wpuf-functions.php:2678
msgid "South Korean Won"
msgstr ""
-#: wpuf-functions.php:2678
+#: wpuf-functions.php:2683
msgid "Malaysian Ringgits"
msgstr ""
-#: wpuf-functions.php:2683
+#: wpuf-functions.php:2688
msgid "Mexican Peso"
msgstr ""
-#: wpuf-functions.php:2688
+#: wpuf-functions.php:2693
msgid "Nigerian Naira"
msgstr ""
-#: wpuf-functions.php:2693
+#: wpuf-functions.php:2698
msgid "Norwegian Krone"
msgstr ""
-#: wpuf-functions.php:2698
+#: wpuf-functions.php:2703
msgid "New Zealand Dollar"
msgstr ""
-#: wpuf-functions.php:2703
+#: wpuf-functions.php:2708
msgid "Namibian dollar"
msgstr ""
-#: wpuf-functions.php:2708
+#: wpuf-functions.php:2713
msgid "Omani Rial"
msgstr ""
-#: wpuf-functions.php:2713
+#: wpuf-functions.php:2718
msgid "Iranian Rial"
msgstr ""
-#: wpuf-functions.php:2718
+#: wpuf-functions.php:2723
msgid "Pakistani Rupee"
msgstr ""
-#: wpuf-functions.php:2723
+#: wpuf-functions.php:2728
msgid "Paraguayan Guaraní"
msgstr ""
-#: wpuf-functions.php:2728
+#: wpuf-functions.php:2733
msgid "Philippine Pesos"
msgstr ""
-#: wpuf-functions.php:2733
+#: wpuf-functions.php:2738
msgid "Polish Zloty"
msgstr ""
-#: wpuf-functions.php:2738
+#: wpuf-functions.php:2743
msgid "Pounds Sterling"
msgstr ""
-#: wpuf-functions.php:2743
+#: wpuf-functions.php:2748
msgid "Romanian Leu"
msgstr ""
-#: wpuf-functions.php:2748
+#: wpuf-functions.php:2753
msgid "Russian Ruble"
msgstr ""
-#: wpuf-functions.php:2753
+#: wpuf-functions.php:2758
msgid "Saudi Riyal"
msgstr ""
-#: wpuf-functions.php:2758
+#: wpuf-functions.php:2763
msgid "Singapore Dollar"
msgstr ""
-#: wpuf-functions.php:2763
+#: wpuf-functions.php:2768
msgid "South African rand"
msgstr ""
-#: wpuf-functions.php:2768
+#: wpuf-functions.php:2773
msgid "Swedish Krona"
msgstr ""
-#: wpuf-functions.php:2773
+#: wpuf-functions.php:2778
msgid "Swiss Franc"
msgstr ""
-#: wpuf-functions.php:2778
+#: wpuf-functions.php:2783
msgid "Taiwan New Dollars"
msgstr ""
-#: wpuf-functions.php:2783
+#: wpuf-functions.php:2788
msgid "Thai Baht"
msgstr ""
-#: wpuf-functions.php:2788
+#: wpuf-functions.php:2793
msgid "Turkish Lira"
msgstr ""
-#: wpuf-functions.php:2793
+#: wpuf-functions.php:2798
msgid "Trinidad and Tobago Dollar"
msgstr ""
-#: wpuf-functions.php:2798
+#: wpuf-functions.php:2803
msgid "US Dollar"
msgstr ""
-#: wpuf-functions.php:2803
+#: wpuf-functions.php:2808
msgid "Vietnamese Dong"
msgstr ""
-#: wpuf-functions.php:2808
+#: wpuf-functions.php:2813
msgid "Egyptian Pound"
msgstr ""
-#: wpuf-functions.php:2813
+#: wpuf-functions.php:2818
msgid "Jordanian dinar"
msgstr ""
-#: wpuf-functions.php:5115
+#: wpuf-functions.php:5120
msgid "General"
msgstr ""
-#: wpuf-functions.php:5129
+#: wpuf-functions.php:5134
msgid "Notification Settings"
msgstr ""
-#: wpuf-functions.php:5135
+#: wpuf-functions.php:5140
msgid "Display Settings"
msgstr ""
-#: wpuf-functions.php:5141
+#: wpuf-functions.php:5146
msgid "Advanced"
msgstr ""
-#: wpuf-functions.php:5159
+#: wpuf-functions.php:5164
msgid "Post Settings"
msgstr ""
-#: wpuf-functions.php:5194
+#: wpuf-functions.php:5199
msgid "-- Select Template --"
msgstr ""
-#: wpuf-functions.php:5196
+#: wpuf-functions.php:5201
msgid "WooCommerce Product Form"
msgstr ""
-#: wpuf-functions.php:5197
+#: wpuf-functions.php:5202
msgid "EDD Download Form"
msgstr ""
-#: wpuf-functions.php:5198
+#: wpuf-functions.php:5203
msgid "Event Form"
msgstr ""
-#: wpuf-functions.php:5199
+#: wpuf-functions.php:5204
msgid "Video Form"
msgstr ""
-#: wpuf-functions.php:5200
+#: wpuf-functions.php:5205
msgid "Professional Video Form"
msgstr ""
-#: wpuf-functions.php:5201
+#: wpuf-functions.php:5206
msgid "Artwork Form"
msgstr ""
-#: wpuf-functions.php:5202
+#: wpuf-functions.php:5207
msgid "Press Release Form"
msgstr ""
-#: wpuf-functions.php:5219
+#: wpuf-functions.php:5224
msgid "Before Post Settings"
msgstr ""
-#: wpuf-functions.php:5220
+#: wpuf-functions.php:5225
msgid ""
"Configure how the form behaves before submission, including content type, "
"default category, post status, draft-saving options, and submit button "
"customization"
msgstr ""
-#: wpuf-functions.php:5226
+#: wpuf-functions.php:5231
msgid "Show Form Title"
msgstr ""
-#: wpuf-functions.php:5228
+#: wpuf-functions.php:5233
msgid "Toggle whether the form title should be displayed on the frontend"
msgstr ""
-#: wpuf-functions.php:5231
+#: wpuf-functions.php:5236
msgid "Form Description"
msgstr ""
-#: wpuf-functions.php:5233
+#: wpuf-functions.php:5238
msgid ""
"Add a brief message or instruction that will be displayed before the form — "
"helpful for guiding users before they start filling it out"
msgstr ""
-#: wpuf-functions.php:5239
+#: wpuf-functions.php:5244
msgid ""
"Select the content type this form will create, like a post, product, or "
"custom type"
msgstr ""
-#: wpuf-functions.php:5248
+#: wpuf-functions.php:5253
msgid "Default Category"
msgstr ""
-#: wpuf-functions.php:5250
+#: wpuf-functions.php:5255
msgid "Select the default category for posts submitted through this form"
msgstr ""
-#: wpuf-functions.php:5256 wpuf-functions.php:5342
+#: wpuf-functions.php:5261 wpuf-functions.php:5347
msgid "Successful Redirection"
msgstr ""
-#: wpuf-functions.php:5258
+#: wpuf-functions.php:5263
msgid "Select where users will be redirected after successfully submitting the form"
msgstr ""
-#: wpuf-functions.php:5264 wpuf-functions.php:5349
+#: wpuf-functions.php:5269 wpuf-functions.php:5354
msgid "Same page"
msgstr ""
-#: wpuf-functions.php:5278 wpuf-functions.php:5372
+#: wpuf-functions.php:5283 wpuf-functions.php:5377
msgid "Choose the default category for the post"
msgstr ""
-#: wpuf-functions.php:5285
+#: wpuf-functions.php:5290
msgid "Post Submission Status"
msgstr ""
-#: wpuf-functions.php:5293
+#: wpuf-functions.php:5298
msgid "Select the status of the post after submission"
msgstr ""
-#: wpuf-functions.php:5296
+#: wpuf-functions.php:5301
msgid "Enable saving as draft"
msgstr ""
-#: wpuf-functions.php:5298
+#: wpuf-functions.php:5303
msgid "Allow users to save posts before final submission"
msgstr ""
-#: wpuf-functions.php:5303
+#: wpuf-functions.php:5308
msgid "Submit Post Button Text"
msgstr ""
-#: wpuf-functions.php:5305
+#: wpuf-functions.php:5310
msgid "Customize the text on the 'Submit' button for this form"
msgstr ""
-#: wpuf-functions.php:5310
+#: wpuf-functions.php:5315
msgid "Choose Form Template"
msgstr ""
-#: wpuf-functions.php:5321
+#: wpuf-functions.php:5326
msgid "After Post Settings"
msgstr ""
-#: wpuf-functions.php:5322
+#: wpuf-functions.php:5327
msgid ""
"Manage what happens after submission, such as setting post update status, "
"displaying success messages, redirecting users, limiting edit time, and "
"customizing the update button"
msgstr ""
-#: wpuf-functions.php:5328
+#: wpuf-functions.php:5333
msgid "Post Update Status"
msgstr ""
-#: wpuf-functions.php:5337
+#: wpuf-functions.php:5342
msgid "Select the status the post will have after being updated"
msgstr ""
-#: wpuf-functions.php:5344
+#: wpuf-functions.php:5349
msgid "After successfully submit, where the page will redirect to"
msgstr ""
-#: wpuf-functions.php:5348
+#: wpuf-functions.php:5353
msgid "Updated post"
msgstr ""
-#: wpuf-functions.php:5358
+#: wpuf-functions.php:5363
msgid ""
"Post has been updated successfully.
View "
"post"
msgstr ""
-#: wpuf-functions.php:5363
+#: wpuf-functions.php:5368
msgid "Customize the message displayed after a post is successfully updated"
msgstr ""
-#: wpuf-functions.php:5379
+#: wpuf-functions.php:5384
msgid "Lock User Editing After"
msgstr ""
-#: wpuf-functions.php:5381
+#: wpuf-functions.php:5386
msgid ""
"Set the number of hours after which users can no longer edit their "
"submitted post"
msgstr ""
-#: wpuf-functions.php:5386
+#: wpuf-functions.php:5391
msgid "Hours"
msgstr ""
-#: wpuf-functions.php:5389
+#: wpuf-functions.php:5394
msgid "Update Post Button Text"
msgstr ""
-#: wpuf-functions.php:5391
+#: wpuf-functions.php:5396
msgid "Customize the text on the 'Update' button for this form"
msgstr ""
-#: wpuf-functions.php:5398
+#: wpuf-functions.php:5403
msgid "Posting Control"
msgstr ""
-#: wpuf-functions.php:5399
+#: wpuf-functions.php:5404
msgid ""
"Define who can submit posts using this form. Choose whether to allow guest "
"submissions or restrict access based on user roles"
msgstr ""
-#: wpuf-functions.php:5405
+#: wpuf-functions.php:5410
msgid "Post Permission"
msgstr ""
-#: wpuf-functions.php:5408
+#: wpuf-functions.php:5413
msgid "- Select Post Permission -"
msgstr ""
-#: wpuf-functions.php:5410
+#: wpuf-functions.php:5415
msgid "Role Based Post"
msgstr ""
-#: wpuf-functions.php:5412
+#: wpuf-functions.php:5417
msgid ""
"Select who can submit posts using this form, either guests or specific user "
"roles"
msgstr ""
-#: wpuf-functions.php:5420
+#: wpuf-functions.php:5425
msgid ""
"If enabled, guest users will be automatically registered using their name "
"and email"
msgstr ""
-#: wpuf-functions.php:5430
+#: wpuf-functions.php:5435
msgid "Customize the label for the name field in guest submissions"
msgstr ""
-#: wpuf-functions.php:5438
+#: wpuf-functions.php:5443
msgid "Customize the label for the email field in guest submissions"
msgstr ""
-#: wpuf-functions.php:5446
+#: wpuf-functions.php:5451
msgid "Require email verification"
msgstr ""
-#: wpuf-functions.php:5448
+#: wpuf-functions.php:5453
msgid "If enabled, users must verify their email before submitting a post"
msgstr ""
-#: wpuf-functions.php:5453
+#: wpuf-functions.php:5458
msgid "Choose who can submit post"
msgstr ""
-#: wpuf-functions.php:5455
+#: wpuf-functions.php:5460
msgid "Select the user roles who can submit posts"
msgstr ""
-#: wpuf-functions.php:5462
+#: wpuf-functions.php:5467
msgid ""
"Display this message to non-logged-in users. Use {login} and {register} "
"placeholders to add login and registration links"
msgstr ""
-#: wpuf-functions.php:5479
+#: wpuf-functions.php:5484
msgid "Enable payments for this form to charge users for submissions"
msgstr ""
-#: wpuf-functions.php:5484
+#: wpuf-functions.php:5489
msgid "Choose Payment Option"
msgstr ""
-#: wpuf-functions.php:5487
+#: wpuf-functions.php:5492
msgid "Mandatory Subscription"
msgstr ""
-#: wpuf-functions.php:5488
+#: wpuf-functions.php:5493
msgid "Pay as you post"
msgstr ""
-#: wpuf-functions.php:5490
+#: wpuf-functions.php:5495
msgid "Select how users will pay for submitting posts"
msgstr ""
-#: wpuf-functions.php:5495
+#: wpuf-functions.php:5500
msgid "Pay-per-post billing when limit exceeds"
msgstr ""
-#: wpuf-functions.php:5497
+#: wpuf-functions.php:5502
msgid "Switch to pay-per-post billing if pack limit is exceeded"
msgstr ""
-#: wpuf-functions.php:5500
+#: wpuf-functions.php:5505
msgid "Cost for each additional post after pack limit is reached"
msgstr ""
-#: wpuf-functions.php:5502
+#: wpuf-functions.php:5507
msgid ""
"This field is required when Pay-per-post billing when limit exceeds is "
"enabled."
msgstr ""
-#: wpuf-functions.php:5505
+#: wpuf-functions.php:5510
msgid "Charge for each post"
msgstr ""
-#: wpuf-functions.php:5507
+#: wpuf-functions.php:5512
msgid ""
"Set a fee for each post submission. This field is required when Pay as you "
"post is selected."
msgstr ""
-#: wpuf-functions.php:5515
+#: wpuf-functions.php:5520
msgid "Select the page to redirect after successful payment."
msgstr ""
-#: wpuf-functions.php:5526
+#: wpuf-functions.php:5531
msgid ""
"Enable email alerts for new post submissions via the frontend form. This "
"feature keeps you updated on user activity, allowing for timely review and "
"approval of content"
msgstr ""
-#: wpuf-functions.php:5534
+#: wpuf-functions.php:5539
msgid "Enable email alerts for new submissions through this form"
msgstr ""
-#: wpuf-functions.php:5575
+#: wpuf-functions.php:5580
msgid ""
"Enable this feature to receive email alerts whenever an existing post is "
"updated through the frontend form. This ensures you're promptly informed "
@@ -9946,95 +10121,95 @@ msgid ""
"updates"
msgstr ""
-#: wpuf-functions.php:5590
+#: wpuf-functions.php:5595
msgid ""
"Customize the appearance and layout of your form. Select a form template "
"that best suits your website's design for a cohesive look and feel"
msgstr ""
-#: wpuf-functions.php:5598
+#: wpuf-functions.php:5603
msgid "Apply your site's theme CSS for consistent styling and appearance"
msgstr ""
-#: wpuf-functions.php:5611
+#: wpuf-functions.php:5616
msgid ""
"Customize the position of form labels for improved user navigation and "
"clarity"
msgstr ""
-#: wpuf-functions.php:5623
+#: wpuf-functions.php:5628
msgid "Enable User Comment"
msgstr ""
-#: wpuf-functions.php:5625
+#: wpuf-functions.php:5630
msgid "Allow users to comment on posts submitted via this form"
msgstr ""
-#: wpuf-functions.php:5632
+#: wpuf-functions.php:5637
msgid "Enable Form Scheduling"
msgstr ""
-#: wpuf-functions.php:5634
+#: wpuf-functions.php:5639
msgid "Set specific dates and times for when the form will be accessible to users"
msgstr ""
-#: wpuf-functions.php:5659
+#: wpuf-functions.php:5664
msgid "Limit Form Entries"
msgstr ""
-#: wpuf-functions.php:5661
+#: wpuf-functions.php:5666
msgid "Limit the number of submissions allowed for the form"
msgstr ""
-#: wpuf-functions.php:5723
+#: wpuf-functions.php:5728
msgid "Saved"
msgstr ""
-#: wpuf-functions.php:5724
+#: wpuf-functions.php:5729
msgid "Trash"
msgstr ""
-#: wpuf-functions.php:5767
+#: wpuf-functions.php:5772
msgid "JPG"
msgstr ""
-#: wpuf-functions.php:5768
+#: wpuf-functions.php:5773
msgid "JPEG"
msgstr ""
-#: wpuf-functions.php:5769
+#: wpuf-functions.php:5774
msgid "PNG"
msgstr ""
-#: wpuf-functions.php:5770
+#: wpuf-functions.php:5775
msgid "GIF"
msgstr ""
-#: wpuf-functions.php:5915
+#: wpuf-functions.php:5920
msgid "Layout 1 - Classic"
msgstr ""
-#: wpuf-functions.php:5916
+#: wpuf-functions.php:5921
msgid "Layout 2 - Modern Dark"
msgstr ""
-#: wpuf-functions.php:5917
+#: wpuf-functions.php:5922
msgid "Layout 3 - Minimal"
msgstr ""
-#: wpuf-functions.php:5918
+#: wpuf-functions.php:5923
msgid "Layout 4 - Bordered"
msgstr ""
-#: wpuf-functions.php:5919
+#: wpuf-functions.php:5924
msgid "Layout 5 - Rounded"
msgstr ""
-#: wpuf-functions.php:5920
+#: wpuf-functions.php:5925
msgid "Layout 6 - Clean"
msgstr ""
-#: wpuf-functions.php:5921
+#: wpuf-functions.php:5926
msgid "Layout 7 - Premium"
msgstr ""
@@ -10050,11 +10225,11 @@ msgstr ""
msgid " or greater."
msgstr ""
-#: wpuf.php:260
+#: wpuf.php:273
msgid "Your WP User Frontend Pro is almost ready!"
msgstr ""
-#: wpuf.php:264
+#: wpuf.php:277
#. translators: 1: opening anchor tag, 2: closing anchor tag.
msgid ""
"We've pushed a major update on both
WP User Frontend Free and
WP "
@@ -10146,7 +10321,7 @@ msgctxt "enhanced select"
msgid "Searching…"
msgstr ""
-#: wpuf-functions.php:1731
+#: wpuf-functions.php:1736
msgctxt "tag delimiter"
msgid ","
msgstr ""
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index d73f6b723..ef15c9665 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -929,7 +929,6 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.80.tgz",
"integrity": "sha512-kEWeMwMeIvxYkeg1gTc01awpwLbfMRZXdIhwRcakd/KlK53jmRC26LqcbIt7fnAQTu5GzlnWmzA3H6+l1u6xxQ==",
"dev": true,
- "peer": true,
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -1899,7 +1898,6 @@
"url": "https://github.com/sponsors/ai"
}
],
- "peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001646",
"electron-to-chromium": "^1.5.4",
@@ -4617,7 +4615,6 @@
"resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.3.tgz",
"integrity": "sha512-mKwmo4X2d8/4c/BmcOETHek675uOqw0RuA/zy12jaspWqvTp4+ZeQF1W+OTpcbncnaBsfbQJ6l0l4j+Sn/GmaQ==",
"dev": true,
- "peer": true,
"dependencies": {
"dateformat": "~3.0.3",
"eventemitter2": "~0.4.13",
@@ -8786,7 +8783,6 @@
"url": "https://github.com/sponsors/ai"
}
],
- "peer": true,
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.1",
@@ -8947,7 +8943,6 @@
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
"integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
"dev": true,
- "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -10487,7 +10482,6 @@
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.11.tgz",
"integrity": "sha512-qhEuBcLemjSJk5ajccN9xJFtM/h0AVCPaA6C92jNP+M2J8kX+eMJHI7R2HFKUvvAsMpcfLILMCFYSeDwpMmlUg==",
"dev": true,
- "peer": true,
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",
@@ -11356,7 +11350,6 @@
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.4.tgz",
"integrity": "sha512-RHFCkULitycHVTtelJ6jQLd+KSAAzOgEYorV32R2q++M6COBjKJR6BxqClwp5sf0XaBDjVMuJ9wnNfyAJwjMkA==",
"dev": true,
- "peer": true,
"dependencies": {
"esbuild": "^0.21.3",
"postcss": "^8.4.43",
@@ -11415,7 +11408,6 @@
"version": "3.5.4",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.4.tgz",
"integrity": "sha512-3yAj2gkmiY+i7+22A1PWM+kjOVXjU74UPINcTiN7grIVPyFFI0lpGwHlV/4xydDmobaBn7/xmi+YG8HeSlCTcg==",
- "peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.4",
"@vue/compiler-sfc": "3.5.4",
diff --git a/wpuf-functions.php b/wpuf-functions.php
index ff883eee7..2f7c2ee40 100644
--- a/wpuf-functions.php
+++ b/wpuf-functions.php
@@ -1492,6 +1492,11 @@ function wpuf_shortcode_map( $location, $post_id = null, $args = [], $meta_key =