PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.76
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.76
51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 51.1.51 All 36 releases
king-addons / includes / admin / shared / dark-theme.php

dark-theme.php in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.76, at includes/admin/shared/dark-theme.php

556 lines 16.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Shared Dark Theme Support for King Addons Admin Pages
4 *
5 * Include this file at the top of admin pages to add dark theme support.
6 * Usage: include KING_ADDONS_PATH . 'includes/admin/shared/dark-theme.php';
7 *
8 * @package King_Addons
9 */
10
11 if (!defined('ABSPATH')) {
12 exit;
13 }
14
15 // Ensure V3 segmented control styles are available wherever this helper is used.
16 wp_enqueue_style(
17 'king-addons-admin-v3',
18 KING_ADDONS_URL . 'includes/admin/layouts/shared/admin-v3-styles.css',
19 [],
20 KING_ADDONS_VERSION
21 );
22
23 // Theme mode is per-user. Must be global so functions can access it.
24 global $ka_theme_mode;
25 $ka_theme_mode = get_user_meta(get_current_user_id(), 'king_addons_theme_mode', true);
26 $ka_allowed_theme_modes = ['dark', 'light', 'auto'];
27 if (!in_array($ka_theme_mode, $ka_allowed_theme_modes, true)) {
28 $ka_theme_mode = 'dark';
29 }
30
31 /**
32 * Output the dark theme toggle HTML
33 */
34 function ka_render_dark_theme_toggle() {
35 global $ka_theme_mode;
36 ?>
37 <div class="ka-v3-segmented" id="ka-v3-theme-segment" role="radiogroup" aria-label="<?php echo esc_attr(esc_html__('Theme', 'king-addons')); ?>" data-active="<?php echo esc_attr($ka_theme_mode); ?>">
38 <span class="ka-v3-segmented-indicator" aria-hidden="true"></span>
39 <button type="button" class="ka-v3-segmented-btn" data-theme="light" aria-pressed="<?php echo $ka_theme_mode === 'light' ? 'true' : 'false'; ?>">
40 <span class="ka-v3-segmented-icon" aria-hidden="true">☀︎</span>
41 <?php esc_html_e('Light', 'king-addons'); ?>
42 </button>
43 <button type="button" class="ka-v3-segmented-btn" data-theme="dark" aria-pressed="<?php echo $ka_theme_mode === 'dark' ? 'true' : 'false'; ?>">
44 <span class="ka-v3-segmented-icon" aria-hidden="true"></span>
45 <?php esc_html_e('Dark', 'king-addons'); ?>
46 </button>
47 <button type="button" class="ka-v3-segmented-btn" data-theme="auto" aria-pressed="<?php echo $ka_theme_mode === 'auto' ? 'true' : 'false'; ?>">
48 <span class="ka-v3-segmented-icon" aria-hidden="true"></span>
49 <?php esc_html_e('Auto', 'king-addons'); ?>
50 </button>
51 </div>
52 <?php
53 }
54
55 /**
56 * Output the dark theme CSS
57 */
58 function ka_render_dark_theme_styles() {
59 ?>
60 <style>
61 /* Theme Switch Button */
62 .ka-theme-switch {
63 display: flex;
64 align-items: center;
65 }
66 .ka-theme-toggle {
67 background: none;
68 border: none;
69 padding: 0;
70 cursor: pointer;
71 display: flex;
72 align-items: center;
73 }
74 .ka-theme-switch-track {
75 width: 52px;
76 height: 28px;
77 background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);
78 border-radius: 14px;
79 position: relative;
80 transition: background 0.3s ease;
81 display: flex;
82 align-items: center;
83 justify-content: space-between;
84 padding: 0 6px;
85 }
86 .ka-theme-switch-track::before,
87 .ka-theme-switch-track::after {
88 font-size: 12px;
89 opacity: 0.7;
90 }
91 .ka-theme-switch-thumb {
92 position: absolute;
93 top: 2px;
94 left: 2px;
95 width: 24px;
96 height: 24px;
97 background: #fff;
98 border-radius: 50%;
99 transition: transform 0.3s ease, background 0.3s ease;
100 display: flex;
101 align-items: center;
102 justify-content: center;
103 box-shadow: 0 2px 4px rgba(0,0,0,0.2);
104 }
105 .ka-theme-switch-thumb::before {
106 content: '';
107 position: absolute;
108 top: 50%;
109 left: 50%;
110 transform: translate(-50%, -50%);
111 }
112 .ka-theme-switch-thumb .ka-sun-icon {
113 color: #f59e0b;
114 display: flex;
115 transition: opacity 0.2s ease;
116 }
117 .ka-theme-switch-thumb .ka-moon-icon {
118 color: #6366f1;
119 display: none;
120 transition: opacity 0.2s ease;
121 }
122 .ka-theme-switch-track:hover {
123 box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.2);
124 }
125
126 /* Dark theme switch state */
127 .ka-dark-theme .ka-theme-switch-track {
128 background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
129 }
130 .ka-dark-theme .ka-theme-switch-track::before,
131 .ka-dark-theme .ka-theme-switch-track::after {
132 color: #fff;
133 }
134 .ka-dark-theme .ka-theme-switch-thumb {
135 transform: translateX(24px);
136 background: #1e1b4b;
137 }
138 .ka-dark-theme .ka-theme-switch-thumb::before {
139 color: #c7d2fe;
140 }
141 .ka-dark-theme .ka-theme-switch-thumb .ka-sun-icon {
142 display: none;
143 }
144 .ka-dark-theme .ka-theme-switch-thumb .ka-moon-icon {
145 display: flex;
146 color: #c7d2fe;
147 }
148 .ka-dark-theme .ka-theme-switch-track:hover {
149 box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.3);
150 }
151
152 /* Instant theme switch (no transition) */
153 .ka-no-transition,
154 .ka-no-transition * {
155 transition: none !important;
156 }
157
158 /* ========================================
159 DARK THEME STYLES
160 ======================================== */
161
162 /* WordPress admin background */
163 body.ka-dark-theme #wpcontent,
164 body.ka-dark-theme #wpbody,
165 body.ka-dark-theme #wpbody-content {
166 background: #0f172a;
167 }
168
169 /* Main wrappers */
170 .ka-dark-theme .ka-settings-wrap,
171 .ka-dark-theme .ka-cookie-wrap,
172 .ka-dark-theme .ka-agegate-wrap,
173 .ka-dark-theme .ka-ai-wrap,
174 .ka-dark-theme .ka-wishlist-wrap,
175 .ka-dark-theme .ka-analytics-wrap,
176 .ka-dark-theme .ka-security-wrap,
177 .ka-dark-theme .ka-woo-wrap {
178 background: #0f172a;
179 }
180
181 /* Headers - keep gradients but adjust */
182 .ka-dark-theme .ka-settings-header,
183 .ka-dark-theme .ka-cookie-header,
184 .ka-dark-theme .ka-agegate-header,
185 .ka-dark-theme .ka-ai-header,
186 .ka-dark-theme .ka-wishlist-header,
187 .ka-dark-theme .ka-analytics-header,
188 .ka-dark-theme .ka-security-header,
189 .ka-dark-theme .ka-woo-header {
190 box-shadow: 0 4px 20px rgba(0,0,0,0.3);
191 }
192
193 /* Cards */
194 .ka-dark-theme .ka-card,
195 .ka-dark-theme .ka-section,
196 .ka-dark-theme .ka-stat-card,
197 .ka-dark-theme .ka-stats-card {
198 background: #1e293b;
199 border-color: #334155;
200 box-shadow: 0 1px 3px rgba(0,0,0,0.3);
201 }
202 .ka-dark-theme .ka-card-header,
203 .ka-dark-theme .ka-section-header {
204 background: #1e293b;
205 border-bottom-color: #334155;
206 }
207 .ka-dark-theme .ka-card-header h2,
208 .ka-dark-theme .ka-section-header h2,
209 .ka-dark-theme .ka-card-header h3,
210 .ka-dark-theme .ka-section-title {
211 color: #f1f5f9;
212 }
213 .ka-dark-theme .ka-card-body,
214 .ka-dark-theme .ka-section-body {
215 background: #1e293b;
216 }
217
218 /* Form elements */
219 .ka-dark-theme .ka-row {
220 border-bottom-color: #334155;
221 }
222 .ka-dark-theme .ka-row-label,
223 .ka-dark-theme label {
224 color: #cbd5e1;
225 }
226 .ka-dark-theme .ka-row-desc,
227 .ka-dark-theme .ka-field-desc,
228 .ka-dark-theme .description {
229 color: #94a3b8;
230 }
231 .ka-dark-theme .ka-row-field input[type="text"],
232 .ka-dark-theme .ka-row-field input[type="number"],
233 .ka-dark-theme .ka-row-field input[type="password"],
234 .ka-dark-theme .ka-row-field input[type="email"],
235 .ka-dark-theme .ka-row-field input[type="url"],
236 .ka-dark-theme .ka-row-field textarea,
237 .ka-dark-theme .ka-row-field select,
238 .ka-dark-theme input[type="text"],
239 .ka-dark-theme input[type="number"],
240 .ka-dark-theme input[type="password"],
241 .ka-dark-theme input[type="email"],
242 .ka-dark-theme input[type="url"],
243 .ka-dark-theme textarea,
244 .ka-dark-theme select {
245 background: #0f172a;
246 border-color: #475569;
247 color: #f1f5f9;
248 }
249 .ka-dark-theme .ka-row-field input:focus,
250 .ka-dark-theme input:focus,
251 .ka-dark-theme textarea:focus,
252 .ka-dark-theme select:focus {
253 border-color: #6366f1;
254 box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
255 }
256 .ka-dark-theme input::placeholder,
257 .ka-dark-theme textarea::placeholder {
258 color: #64748b;
259 }
260
261 /* Toggles */
262 .ka-dark-theme .ka-toggle-slider {
263 background: #475569;
264 }
265 .ka-dark-theme .ka-toggle input:checked + .ka-toggle-slider {
266 background: #6366f1;
267 }
268
269 /* Tabs */
270 .ka-dark-theme .ka-tabs {
271 background: #1e293b;
272 }
273 .ka-dark-theme .ka-tab {
274 color: #94a3b8;
275 background: transparent;
276 }
277 .ka-dark-theme .ka-tab:hover {
278 background: #334155;
279 color: #f1f5f9;
280 }
281 .ka-dark-theme .ka-tab.active {
282 background: #6366f1;
283 color: #fff;
284 }
285
286 /* Tables */
287 .ka-dark-theme table {
288 background: #1e293b;
289 border-color: #334155;
290 }
291 .ka-dark-theme th {
292 background: #0f172a;
293 color: #f1f5f9;
294 border-color: #334155;
295 }
296 .ka-dark-theme td {
297 color: #cbd5e1;
298 border-color: #334155;
299 }
300 .ka-dark-theme tr:hover td {
301 background: #334155;
302 }
303
304 /* Buttons */
305 .ka-dark-theme .button {
306 background: #334155;
307 border-color: #475569;
308 color: #f1f5f9;
309 transition: all 0.2s;
310 }
311 .ka-dark-theme .button:hover {
312 background: #475569;
313 border-color: #6366f1;
314 color: #fff;
315 }
316 .ka-dark-theme .button-primary,
317 .ka-dark-theme .ka-btn-primary {
318 background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
319 border: none;
320 color: #fff;
321 transition: transform 0.2s, box-shadow 0.2s, background 0.2s;
322 }
323 .ka-dark-theme .button-primary:hover,
324 .ka-dark-theme .ka-btn-primary:hover {
325 background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
326 color: #fff;
327 transform: translateY(-1px);
328 box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
329 }
330
331 /* Submit area */
332 .ka-dark-theme .ka-submit,
333 .ka-dark-theme .ka-card-footer {
334 background: #0f172a;
335 border-top-color: #334155;
336 }
337
338 /* Status badges */
339 .ka-dark-theme .ka-status-enabled {
340 background: rgba(34, 197, 94, 0.2);
341 color: #4ade80;
342 }
343 .ka-dark-theme .ka-status-disabled {
344 background: rgba(239, 68, 68, 0.2);
345 color: #f87171;
346 }
347
348 /* Text colors */
349 .ka-dark-theme h1, .ka-dark-theme h2, .ka-dark-theme h3, .ka-dark-theme h4 {
350 color: #f1f5f9;
351 }
352 .ka-dark-theme p, .ka-dark-theme span, .ka-dark-theme div {
353 color: #cbd5e1;
354 }
355 .ka-dark-theme a {
356 color: #818cf8;
357 }
358 .ka-dark-theme a:hover {
359 color: #a5b4fc;
360 }
361
362 .ka-dark-theme a.ka-hf-btn-primary {
363 color: #fff;
364 }
365
366 .ka-dark-theme a.ka-wb-dropdown-item{
367 color: var(--ka-wb-text);
368 }
369
370 .ka-dark-theme a.ka-wb-dropdown-item.is-danger {
371 color: #ff3b30;
372 }
373
374 /* Stat cards */
375 .ka-dark-theme .ka-stat-value,
376 .ka-dark-theme .ka-stat-number {
377 color: #f1f5f9;
378 }
379 .ka-dark-theme .ka-stat-label {
380 color: #94a3b8;
381 }
382 .ka-dark-theme .ka-stat-icon {
383 background: rgba(99, 102, 241, 0.2);
384 }
385
386 /* Code/Pre */
387 .ka-dark-theme code,
388 .ka-dark-theme pre {
389 background: #0f172a;
390 color: #e2e8f0;
391 border-color: #334155;
392 }
393
394 /* Notices */
395 .ka-dark-theme .ka-notice,
396 .ka-dark-theme .notice {
397 background: #1e293b;
398 border-color: #475569;
399 color: #cbd5e1;
400 }
401
402 /* Specific page adjustments */
403 .ka-dark-theme .ka-log-entry {
404 background: #0f172a;
405 border-color: #334155;
406 }
407
408 /* WooCommerce Builder specific */
409 .ka-dark-theme .ka-woo-grid .ka-woo-card {
410 background: #1e293b;
411 border-color: #334155;
412 }
413 .ka-dark-theme .ka-woo-card:hover {
414 border-color: #6366f1;
415 }
416 .ka-dark-theme .ka-woo-card-title {
417 color: #f1f5f9;
418 }
419 .ka-dark-theme .ka-woo-card-desc {
420 color: #94a3b8;
421 }
422
423 /* Filter bar */
424 .ka-dark-theme .ka-filter-bar {
425 background: #1e293b;
426 border-color: #334155;
427 }
428
429 /* Scrollbar */
430 .ka-dark-theme ::-webkit-scrollbar {
431 width: 8px;
432 height: 8px;
433 }
434 .ka-dark-theme ::-webkit-scrollbar-track {
435 background: #1e293b;
436 }
437 .ka-dark-theme ::-webkit-scrollbar-thumb {
438 background: #475569;
439 border-radius: 4px;
440 }
441 .ka-dark-theme ::-webkit-scrollbar-thumb:hover {
442 background: #64748b;
443 }
444 </style>
445 <?php
446 }
447
448 /**
449 * Output the dark theme JavaScript
450 */
451 function ka_render_dark_theme_script() {
452 ?>
453 <script>
454 (function($) {
455 'use strict';
456
457 // AJAX settings
458 const ajaxUrl = '<?php echo esc_url(admin_url('admin-ajax.php')); ?>';
459 const nonce = '<?php echo esc_js(wp_create_nonce('king_addons_dashboard_ui')); ?>';
460
461 // Save UI setting via AJAX
462 function saveUISetting(key, value) {
463 $.post(ajaxUrl, {
464 action: 'king_addons_save_dashboard_ui',
465 nonce: nonce,
466 key: key,
467 value: value
468 });
469 }
470
471 const themeMql = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
472 let themeMode = ($('#ka-v3-theme-segment').attr('data-active') || 'dark').toString();
473 let themeMqlHandler = null;
474
475 function applyThemeClasses(isDark) {
476 if (isDark) {
477 $('body').addClass('ka-dark-theme');
478 } else {
479 $('body').removeClass('ka-dark-theme');
480 }
481
482 $('body').toggleClass('ka-v3-dark', isDark);
483 document.documentElement.classList.toggle('ka-v3-dark', isDark);
484 }
485
486 function updateSegment(mode) {
487 var $segment = $('#ka-v3-theme-segment');
488 if (!$segment.length) {
489 return;
490 }
491 $segment.attr('data-active', mode);
492 $segment.find('.ka-v3-segmented-btn').each(function() {
493 var theme = $(this).data('theme');
494 $(this).attr('aria-pressed', theme === mode ? 'true' : 'false');
495 });
496 }
497
498 function setThemeMode(mode, save) {
499 themeMode = mode;
500 updateSegment(mode);
501
502 if (themeMqlHandler && themeMql) {
503 if (themeMql.removeEventListener) {
504 themeMql.removeEventListener('change', themeMqlHandler);
505 } else if (themeMql.removeListener) {
506 themeMql.removeListener(themeMqlHandler);
507 }
508 themeMqlHandler = null;
509 }
510
511 if (mode === 'auto') {
512 applyThemeClasses(!!(themeMql && themeMql.matches));
513 themeMqlHandler = function(e) {
514 if (themeMode !== 'auto') {
515 return;
516 }
517 applyThemeClasses(!!e.matches);
518 };
519 if (themeMql) {
520 if (themeMql.addEventListener) {
521 themeMql.addEventListener('change', themeMqlHandler);
522 } else if (themeMql.addListener) {
523 themeMql.addListener(themeMqlHandler);
524 }
525 }
526 } else {
527 applyThemeClasses(mode === 'dark');
528 }
529
530 if (save) {
531 saveUISetting('theme_mode', mode);
532 }
533 }
534
535 // Theme segmented control click
536 $(document).on('click', '#ka-v3-theme-segment .ka-v3-segmented-btn', function(e) {
537 e.preventDefault();
538 setThemeMode(($(this).data('theme') || 'dark').toString(), true);
539 });
540
541 // Apply current mode (incl. Auto listener)
542 setThemeMode(themeMode, false);
543 })(jQuery);
544 </script>
545 <?php
546 }
547
548 /**
549 * Output inline script to apply dark theme immediately (before page renders)
550 */
551 function ka_render_dark_theme_init() {
552 global $ka_theme_mode;
553 $mode = esc_js($ka_theme_mode);
554 echo '<script>(function(){var mode="' . $mode . '";var mql=window.matchMedia?window.matchMedia("(prefers-color-scheme: dark)"):null;function apply(isDark){document.documentElement.classList.toggle("ka-v3-dark",!!isDark);if(document.body){document.body.classList.toggle("ka-v3-dark",!!isDark);document.body.classList.toggle("ka-dark-theme",!!isDark);}}function ensureBody(fn){if(document.body){fn();return;}document.addEventListener("DOMContentLoaded",fn,{once:true});}if(mode==="auto"){var isDark=!!(mql&&mql.matches);apply(isDark);ensureBody(function(){apply(isDark);});}else{var dark=(mode==="dark");apply(dark);ensureBody(function(){apply(dark);});}})();</script>';
555 }
556