PluginProbe
Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) / 2.1.3
Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) v2.1.3
2.1.3 2.1.2 2.1.1 2.1.0 2.0.4 2.0.3 2.0.2 2.0.1 2.0.0 1.5.5 1.5.4 1.5.3 1.5.2 1.5.1 1.5.0 trunk 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 All 57 releases
← All changes | src/Admin/Views/Control.php +313 -280 1.5.42.1.3 View file →
@@ -12,9 +12,9 @@
12 12 */
13 13
14 14 namespace ThemeAtelier\Darkify\Admin\Views;
15 15
16 -use ThemeAtelier\Darkify\Admin\Framework\Classes\Darkify;
16 +use ThemeAtelier\Darkify\Admin\Schema\SchemaRegistry as Darkify;
17 17
18 18 class Control
19 19 {
20 20 /**
@@ -27,41 +27,55 @@
27 27 {
28 28 Darkify::createSection(
29 29 $prefix,
30 30 array(
31 - 'title' => esc_html__('CONTROLS', 'darkify'),
31 + // Explicit, locale-independent id. Without it the REST layer falls
32 + // back to sanitize_title() of the *translated* title, so the route
33 + // became #/sterowanie on a Polish site and every link 404'd inside
34 + // the SPA. Value matches the old English slug so existing
35 + // `#tab=` / `#/controls` bookmarks keep resolving.
36 + 'id' => 'controls',
37 + 'title' => esc_html__('Controls', 'darkify'),
32 38 'icon' => 'icofont-ui-settings',
33 39 'fields' => array(
34 40 array(
35 - 'type' => 'notice',
36 - 'content' => __('<h3>Things Not Working as Expected?</h3>Every theme and page layout is built differently. If a section doesn’t turn dark, it’s usually using a background image, inline style, or custom CSS. Use Darkify’s control settings (color overrides, image filters, exclusions, or custom CSS) to fine-tune the result. If you still need help, <a href="https://wordpress.org/support/plugin/darkify/#new-topic-0" target="_blank">create a support topic</a> anytime—we’re happy to assist.', 'darkify'),
37 - ),
38 - array(
39 41 'type' => 'section_tab',
40 42 'tabs' => array(
41 43
42 44 array(
45 + 'id' => 'frontend',
43 46 'title' => esc_html__('Frontend', 'darkify'),
44 47 'icon' => 'icofont-computer',
45 48 'fields' => array(
49 + // Intro line with a docs link, rendered plain above the section cards.
46 50 array(
47 - 'type' => 'heading',
48 - 'content' => esc_html__('Basic Controls', 'darkify'),
51 + 'type' => 'page_hint',
52 + 'content' => sprintf(
53 + /* translators: %s: documentation link */
54 + __('Decide how and when dark mode turns on for visitors on your public website. %s', 'darkify'),
55 + '<a href="https://darkifywp.com/docs/" target="_blank" rel="noopener noreferrer">' . esc_html__('View documentation', 'darkify') . '</a>'
56 + ),
49 57 ),
58 +
59 + // ===== AVAILABILITY =====
50 60 array(
61 + 'type' => 'heading',
62 + 'title' => esc_html__('Availability', 'darkify'),
63 + 'section_start' => true,
64 + ),
65 + array(
51 66 'id' => 'enable_dark_mode_switch',
52 67 'type' => 'switcher',
53 68 'title' => esc_html__('Frontend Dark Mode', 'darkify'),
54 69 'title_help' => '<div class="darkify-info-label">' .
55 - __('Show the dark mode floating switch on your website frontend.', 'darkify') .
56 - '</div>' . '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#basic-control-options') . '" target="_blank" rel="noopener noreferrer">' .
57 - esc_html__('Live Demo', 'darkify') . '</a>' . '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#basic-control-options') . '" target="_blank" rel="noopener noreferrer">' .
58 - esc_html__('Open Docs', 'darkify') .
59 - '</a>',
70 + __('Show the dark mode floating switch on your website frontend. This is the master control for everything below.', 'darkify') .
71 + '</div>' . '' . '',
60 72 'text_on' => esc_html__('Enabled', 'darkify'),
61 73 'text_off' => esc_html__('Disabled', 'darkify'),
62 74 'text_width' => 100,
63 75 'default' => true,
76 + // Commit instantly (master toggle governs the whole frontend feature).
77 + 'auto_save' => true,
64 78 ),
65 79 array(
66 80 'id' => 'enable_default_dark_mode',
67 81 'type' => 'switcher',
@@ -69,17 +83,16 @@
69 83 'title_help' =>
70 84 '<div class="darkify-info-label">' .
71 85 __('Enable dark mode by default on your website.', 'darkify') .
72 86 '</div>' .
73 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#basic-control-options') . '" target="_blank" rel="noopener noreferrer">' .
74 - esc_html__('Live Demo', 'darkify') .
75 - '</a>' .
76 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#basic-control-options') . '" target="_blank" rel="noopener noreferrer">' .
77 - esc_html__('Open Docs', 'darkify') .
78 - '</a>',
87 + '' .
88 + '',
79 89 'text_on' => esc_html__('Enabled', 'darkify'),
80 90 'text_off' => esc_html__('Disabled', 'darkify'),
81 91 'text_width' => 100,
92 + // Commit instantly (the priority notice depends on it, which would
93 + // otherwise force the manual-Save workflow).
94 + 'auto_save' => true,
82 95 ),
83 96 array(
84 97 'id' => 'enable_os_aware',
85 98 'type' => 'switcher',
@@ -87,61 +100,55 @@
87 100 'title_help' =>
88 101 '<div class="darkify-info-label">' .
89 102 __('Toggle dark mode based on the user’s device or operating system preference.', 'darkify') .
90 103 '</div>' .
91 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#basic-control-options') . '" target="_blank" rel="noopener noreferrer">' .
92 - esc_html__('Live Demo', 'darkify') .
93 - '</a>' .
94 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#basic-control-options') . '" target="_blank" rel="noopener noreferrer">' .
95 - esc_html__('Open Docs', 'darkify') .
96 - '</a>',
104 + '' .
105 + '',
97 106 'text_on' => esc_html__('Enabled', 'darkify'),
98 107 'text_off' => esc_html__('Disabled', 'darkify'),
99 108 'text_width' => 100,
100 109 'default' => true,
110 + // Commit instantly (the priority notice depends on it).
111 + 'auto_save' => true,
101 112 ),
113 + // Priority notice: shown only when Default Dark Mode AND OS Aware are both on.
102 114 array(
115 + 'type' => 'submessage',
116 + 'style' => 'info',
117 + 'content' => '<strong>' . esc_html__('OS Aware takes priority.', 'darkify') . '</strong> ' . esc_html__('Both are on, so visitors following the system “dark” setting get dark mode automatically; Default Dark Mode applies only when no system preference is detected.', 'darkify'),
118 + 'dependency' => array('enable_default_dark_mode|enable_os_aware', '==|==', 'true|true'),
119 + ),
120 +
121 + // ===== ACTIVATION =====
122 + array(
123 + 'type' => 'heading',
124 + 'title' => esc_html__('Activation', 'darkify'),
125 + 'section_start' => true,
126 + ),
127 + array(
103 128 'id' => 'enable_keyboard_shortcut',
104 129 'type' => 'switcher',
105 130 'title' => esc_html__('Keyboard Shortcut', 'darkify'),
106 131 'title_help' =>
107 132 '<div class="darkify-info-label">' .
108 - __('Toggle dark mode using a keyboard shortcut. Use Ctrl + Alt + D on Windows, and Control + Option + D on macOS.', 'darkify') .
133 + __('Let visitors toggle dark mode with a keyboard shortcut.', 'darkify') .
109 134 '</div>' .
110 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#basic-control-options') . '" target="_blank" rel="noopener noreferrer">' .
111 - esc_html__('Live Demo', 'darkify') .
112 - '</a>' .
113 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#basic-control-options') . '" target="_blank" rel="noopener noreferrer">' .
114 - esc_html__('Open Docs', 'darkify') .
115 - '</a>',
135 + '' .
136 + '',
116 137 'text_on' => esc_html__('Enabled', 'darkify'),
117 138 'text_off' => esc_html__('Disabled', 'darkify'),
118 139 'text_width' => 100,
119 140 'default' => true,
141 + // Commit instantly (the shortcut-keys field depends on it).
142 + 'auto_save' => true,
120 143 ),
144 + // Editable shortcut combo (shown when the shortcut is enabled).
121 145 array(
122 - 'id' => 'enable_frontend_iframe_dark_mode',
123 - 'type' => 'switcher',
124 - 'title' => esc_html__('Frontend Iframe Dark Mode', 'darkify'),
125 - 'title_help' =>
126 - '<div class="darkify-info-label">' .
127 - __('Apply dark mode inside frontend iframes (e.g. embedded widgets or same-origin frames). Disable this if you want iframes to keep their original light appearance while the rest of the page uses dark mode.', 'darkify') .
128 - '</div>' .
129 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#basic-control-options') . '" target="_blank" rel="noopener noreferrer">' .
130 - esc_html__('Live Demo', 'darkify') .
131 - '</a>' .
132 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#basic-control-options') . '" target="_blank" rel="noopener noreferrer">' .
133 - esc_html__('Open Docs', 'darkify') .
134 - '</a>',
135 - 'text_on' => esc_html__('Enabled', 'darkify'),
136 - 'text_off' => esc_html__('Disabled', 'darkify'),
137 - 'text_width' => 100,
138 - 'default' => true,
146 + 'id' => 'keyboard_shortcut_keys',
147 + 'type' => 'keyboard_shortcut',
148 + 'default' => 'ctrl+alt+d',
149 + 'dependency' => array('enable_keyboard_shortcut', '==', 'true'),
139 150 ),
140 - array(
141 - 'type' => 'heading',
142 - 'title' => esc_html__('Advanced Controls', 'darkify'),
143 - ),
144 151 // Enable Time Based Auto Dark Mode
145 152 array(
146 153 'id' => 'enable_time',
147 154 'type' => 'fieldset',
@@ -153,14 +160,10 @@
153 160 'title_help' =>
154 161 '<div class="darkify-info-label">' .
155 162 __('Automatically enable dark mode based on the user’s local time.', 'darkify') .
156 163 '</div>' .
157 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
158 - esc_html__('Live Demo', 'darkify') .
159 - '</a>' .
160 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
161 - esc_html__('Open Docs', 'darkify') .
162 - '</a>',
164 + '' .
165 + '',
163 166 'text_on' => esc_html__('Enabled', 'darkify'),
164 167 'text_off' => esc_html__('Disabled', 'darkify'),
165 168 'text_width' => 100,
166 169 ),
@@ -173,16 +176,34 @@
173 176 'title_help' =>
174 177 '<div class="darkify-info-label">' .
175 178 __('Set the exact start and end times when dark mode should be automatically enabled or disabled.', 'darkify') .
176 179 '</div>' .
177 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
178 - esc_html__('Live Demo', 'darkify') .
179 - '</a>' .
180 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
181 - esc_html__('Open Docs', 'darkify') .
182 - '</a>',
180 + '' .
181 + '',
183 182 'fields' => array(
183 + /*
184 + * Which clock drives the schedule. Darkify Lite ships
185 + * only "fixed" (the start/end window below); the
186 + * sunrise/sunset schedule is a Pro feature, so its
187 + * option row carries `pro_only` — the REST layer turns
188 + * that into the `pro_options` stamp the React admin
189 + * renders as a locked, badged preview, and
190 + * strip_pro_keys() refuses to persist the value even
191 + * if a crafted request sends it.
192 + */
184 193 array(
194 + 'id' => 'time_based_dark_mode',
195 + 'type' => 'button_set',
196 + 'default' => 'fixed',
197 + 'options' => array(
198 + 'fixed' => esc_html__('Fixed times', 'darkify'),
199 + 'suncycle' => array(
200 + 'text' => esc_html__('Sunrise & sunset', 'darkify'),
201 + 'pro_only' => true,
202 + ),
203 + ),
204 + ),
205 + array(
185 206 'id' => 'time_based_dark_start',
186 207 'type' => 'datetime',
187 208 'after' => esc_html__('From', 'darkify'),
188 209 'placeholder' => esc_html__('From', 'darkify'),
@@ -208,203 +229,31 @@
208 229 ),
209 230 ),
210 231 ),
211 232 ),
212 - array(
213 - 'id' => 'hide_on_desktop',
214 - 'type' => 'switcher',
215 - 'title' => esc_html__('Hide Dark Mode Switch on Desktop', 'darkify'),
216 - 'title_help' =>
217 - '<div class="darkify-info-label">' .
218 - __('Hide the dark mode floating switch when users are browsing on a desktop or laptop.', 'darkify') .
219 - '</div>' .
220 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
221 - esc_html__('Live Demo', 'darkify') .
222 - '</a>' .
223 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
224 - esc_html__('Open Docs', 'darkify') .
225 - '</a>',
226 -
227 - 'text_on' => esc_html__('Yes', 'darkify'),
228 - 'text_off' => esc_html__('No', 'darkify'),
229 -
230 - ),
231 - array(
232 - 'id' => 'hide_on_mobile',
233 - 'type' => 'fieldset',
234 - 'fields' => array(
235 - array(
236 - 'id' => 'hide_dark_mode_on_mobile',
237 - 'type' => 'switcher',
238 - 'title' => esc_html__('Hide Dark Mode on Mobile', 'darkify'),
239 - 'title_help' =>
240 - '<div class="darkify-info-label">' .
241 - __('Hide the dark mode floating switch when users are browsing on mobile devices.', 'darkify') .
242 - '</div>' .
243 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
244 - esc_html__('Live Demo', 'darkify') .
245 - '</a>' .
246 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
247 - esc_html__('Open Docs', 'darkify') .
248 - '</a>',
249 -
250 - 'text_on' => esc_html__('Yes', 'darkify'),
251 - 'text_off' => esc_html__('No', 'darkify'),
252 -
253 - ),
254 - array(
255 - 'id' => 'type_of_hide_by',
256 - 'type' => 'button_set',
257 - 'title' => esc_html__('Hide Detection Method', 'darkify'),
258 -
259 - 'title_help' =>
260 - '<div class="darkify-info-label">' .
261 - __('Choose how mobile devices are detected: by User Agent, by Screen Size, or use Both for maximum accuracy.', 'darkify') .
262 - '</div>' .
263 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
264 - esc_html__('Live Demo', 'darkify') .
265 - '</a>' .
266 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
267 - esc_html__('Open Docs', 'darkify') .
268 - '</a>',
269 -
270 - 'options' => array(
271 - 'user_agent' => esc_html__('User Agent', 'darkify'),
272 - 'screen_size' => esc_html__('Screen Size', 'darkify'),
273 - 'both' => esc_html__('Both', 'darkify'),
274 - ),
275 -
276 - 'default' => 'both',
277 - 'dependency' => array('hide_dark_mode_on_mobile', '==', 'true'),
278 - ),
279 - ),
280 - ),
281 - array(
282 - 'id' => 'show_in_menu',
283 - 'type' => 'fieldset',
284 - 'fields' => array(
285 - array(
286 - 'id' => 'enable_switch_in_menu',
287 - 'type' => 'switcher',
288 - 'title' => esc_html__('Show Switch in Menu', 'darkify'),
289 -
290 - 'title_help' =>
291 - '<div class="darkify-info-label">' .
292 - __('Show the dark mode toggle switch in a selected menu.', 'darkify') .
293 - '</div>' .
294 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
295 - esc_html__('Live Demo', 'darkify') .
296 - '</a>' .
297 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#menu-integration') . '" target="_blank" rel="noopener noreferrer">' .
298 - esc_html__('Open Docs', 'darkify') .
299 - '</a>',
300 -
301 - 'text_on' => esc_html__('Yes', 'darkify'),
302 - 'text_off' => esc_html__('No', 'darkify'),
303 -
304 - ),
305 - array(
306 - 'id' => 'select_menus',
307 - 'type' => 'group',
308 - 'title' => esc_html__('Menu Switch Settings', 'darkify'),
309 -
310 - 'title_help' =>
311 - '<div class="darkify-info-label">' .
312 - __('Configure menu switch options and placement for your site.', 'darkify') .
313 - '</div>' .
314 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
315 - esc_html__('Live Demo', 'darkify') .
316 - '</a>' .
317 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#menu-integration') . '" target="_blank" rel="noopener noreferrer">' .
318 - esc_html__('Open Docs', 'darkify') .
319 - '</a>',
320 -
321 - 'add_more_text' => sprintf(
322 - /* translators: %s: URL to the Darkify Pro pricing page. */
323 - __(
324 - 'Want to use the switch in an unlimited number of menus? <a target="_blank" href="%s"><strong>Upgrade to Pro</strong></a>.',
325 - 'darkify'
326 - ),
327 - esc_url(DARKIFY_DEMO_URL . 'pricing/?ref=1')
328 - ),
329 -
330 - 'accordion_title_number' => true,
331 - 'accordion_title_auto' => true,
332 - 'class' => 'select_menus',
333 - 'max' => 1,
334 -
335 - 'fields' => array(
336 - array(
337 - 'id' => 'switch_in_menu_location',
338 - 'type' => 'select',
339 - 'class' => 'select_menu_location',
340 - 'title' => esc_html__('Select Menu', 'darkify'),
341 - 'title_help' =>
342 - '<div class="darkify-info-label">' .
343 - esc_html__('Choose a menu from the dropdown list.', 'darkify') .
344 - '</div>' .
345 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
346 - esc_html__('Live Demo', 'darkify') .
347 - '</a>' .
348 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#menu-integration') . '" target="_blank" rel="noopener noreferrer">' .
349 - esc_html__('Open Docs', 'darkify') .
350 - '</a>',
351 - 'empty_message' => esc_html__(
352 - 'You have not created a menu yet. If you are using a Full Site Editing (FSE) theme, copy the shortcode below and paste it where you want the switch to appear.',
353 - 'darkify'
354 - ),
355 - 'options' => 'menus',
356 - ),
357 - array(
358 - 'id' => 'darkify_menu_shortcode_helper',
359 - 'type' => 'textarea',
360 - 'title' => esc_html__('Shortcode for Menu', 'darkify'),
361 - 'title_help' =>
362 - '<div class="darkify-info-label">' .
363 - __('You can customize the shortcode options based on your preference.', 'darkify') .
364 - '</div>' .
365 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
366 - esc_html__('Live Demo', 'darkify') .
367 - '</a>' .
368 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#menu-integration') . '" target="_blank" rel="noopener noreferrer">' .
369 - esc_html__('Open Docs', 'darkify') .
370 - '</a>',
371 - 'default' => '[darkify switch="1" light_mode_bg="#121116" dark_mode_bg="#ffffff" light_mode_color="#ffffff" dark_mode_color="#121116" border="0px" border_light_color="#121119" border_dark_color="#ffffff" border_radius="7px" switch_size="100"]'
372 - ),
373 - array(
374 - 'id' => 'select_menu_position',
375 - 'type' => 'button_set',
376 - 'title' => esc_html__('Select Menu Position', 'darkify'),
377 - 'title_help' =>
378 - '<div class="darkify-info-label">' .
379 - esc_html__('Choose where the dark mode switch should appear in the menu.', 'darkify') .
380 - '</div>' .
381 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#advanced-control-options') . '" target="_blank" rel="noopener noreferrer">' .
382 - esc_html__('Live Demo', 'darkify') .
383 - '</a>' .
384 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'control/#menu-integration') . '" target="_blank" rel="noopener noreferrer">' .
385 - esc_html__('Open Docs', 'darkify') .
386 - '</a>',
387 -
388 - 'options' => array(
389 - 'after' => esc_html__('After', 'darkify'),
390 - 'before' => esc_html__('Before', 'darkify'),
391 - ),
392 -
393 - 'default' => 'after',
394 - ),
395 - ),
396 - 'dependency' => array('enable_switch_in_menu', '==', 'true'),
397 - ),
398 - ),
399 - ),
400 233 ),
401 234 ),
402 235 array(
236 + 'id' => 'admin',
403 237 'title' => esc_html__('Admin', 'darkify'),
404 238 'icon' => 'icofont-dashboard-web',
405 239 'fields' => array(
240 + // Intro line with a docs link, rendered plain above the section cards.
406 241 array(
242 + 'type' => 'page_hint',
243 + 'content' => sprintf(
244 + /* translators: %s: documentation link */
245 + __('Bring dark mode to the WordPress admin dashboard and editors. %s', 'darkify'),
246 + '<a href="https://darkifywp.com/docs/" target="_blank" rel="noopener noreferrer">' . esc_html__('View documentation', 'darkify') . '</a>'
247 + ),
248 + ),
249 + // ===== ADMIN APPEARANCE =====
250 + array(
251 + 'type' => 'heading',
252 + 'title' => esc_html__('Admin Appearance', 'darkify'),
253 + 'section_start' => true,
254 + ),
255 + array(
407 256 'id' => 'enable_admin_panel_dark_mode',
408 257 'type' => 'switcher',
409 258 'title' => esc_html__('Admin Panel Dark Mode', 'darkify'),
410 259 'title_help' =>
@@ -410,21 +259,125 @@
410 259 'title_help' =>
411 260 '<div class="darkify-info-label">' .
412 261 __('Enable dark mode in the WordPress admin dashboard.', 'darkify') .
413 262 '</div>' .
414 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#admin') . '" target="_blank" rel="noopener noreferrer">' .
415 - esc_html__('Live Demo', 'darkify') .
416 - '</a>' .
417 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'controls/#admin-controls') . '" target="_blank" rel="noopener noreferrer">' .
418 - esc_html__('Open Docs', 'darkify') .
419 - '</a>',
263 + '' .
264 + '',
420 265 'text_on' => esc_html__('Enabled', 'darkify'),
421 266 'text_off' => esc_html__('Disabled', 'darkify'),
422 267 'default' => false,
423 268 'text_width' => 100,
269 + // Commit instantly even though other fields depend on it.
270 + 'auto_save' => true,
424 271 ),
425 272
273 + /*
274 + * Admin palettes are separate from the frontend's `color_pallets`
275 + * and from each other. wp-admin is rendered by Dark Reader, which
276 + * derives a colour per source colour; a preset overrides only the
277 + * page background and text colour and lets it derive the rest.
278 + *
279 + * "Auto" is the default and the recommended value: pinning those two
280 + * flattens distinctions the derivation would otherwise keep, which
281 + * matters most on admin screens built by other plugins.
282 + *
283 + * Only the five presets darkify_apply_palette() actually defines are
284 + * listed. The block editor's toolbar dropdown offers more than that
285 + * and silently falls back for the rest — do not copy that list here.
286 + *
287 + * The swatch colours match the toolbar dropdown (.darkify-dropdown in
288 + * src/assets/css/client_main.css) so the same preset is recognisable
289 + * in both places. "Auto" shows a gradient: it has no single colour.
290 + *
291 + * These are the site-wide default. The editor's toolbar dropdown
292 + * still writes a per-user choice to localStorage, which wins for
293 + * that user — the same relationship the toolbar has always had.
294 + */
426 295 array(
296 + 'id' => 'admin_panel_palette',
297 + 'type' => 'select',
298 + 'title' => esc_html__('Admin Panel Palette', 'darkify'),
299 + 'title_help' =>
300 + '<div class="darkify-info-label">' .
301 + __('Color preset for the WordPress admin. Auto lets Darkify derive each color from the original.', 'darkify') .
302 + '</div>',
303 + 'default' => 'auto',
304 + 'options' => array(
305 + 'auto' => array(
306 + 'text' => esc_html__('Auto (recommended)', 'darkify'),
307 + 'swatch' => 'linear-gradient(135deg, #0f0f0f 0%, #3a3a3a 50%, #8f8f8f 100%)',
308 + ),
309 + 'set1' => array(
310 + 'text' => esc_html__('Carbon Mist', 'darkify'),
311 + 'swatch' => '#171717',
312 + ),
313 + 'set3' => array(
314 + 'text' => esc_html__('Midnight Reverie', 'darkify'),
315 + 'swatch' => '#4e478d',
316 + ),
317 + 'set9' => array(
318 + 'text' => esc_html__('Verdant Depths', 'darkify'),
319 + 'swatch' => '#073d2f',
320 + ),
321 + 'set6' => array(
322 + 'text' => esc_html__('Celestial Tide', 'darkify'),
323 + 'swatch' => '#144e78',
324 + ),
325 + 'set10' => array(
326 + 'text' => esc_html__('Emberwood', 'darkify'),
327 + 'swatch' => '#372911',
328 + ),
329 +
330 + /*
331 + * Pro presets, listed after every one that works here so the
332 + * usable list is not diluted at the top.
333 + *
334 + * These are not new upsell surface. The block editor's toolbar
335 + * dropdown has always offered all eleven names while
336 + * darkify_apply_palette() defines only five, so picking one of
337 + * these silently rendered Carbon Mist — they looked broken
338 + * rather than gated. Marking them is what makes that honest.
339 + *
340 + * `pro_only` is the whole mechanism: locked_option_keys() turns
341 + * it into the `pro_options` stamp the React admin renders as a
342 + * disabled, badged row, and strip_pro_keys() refuses to persist
343 + * the value even if a crafted request sends it.
344 + */
345 + 'set2' => array(
346 + 'text' => esc_html__('Glacier Drift', 'darkify'),
347 + 'swatch' => '#123d52',
348 + 'pro_only' => true,
349 + ),
350 + 'set4' => array(
351 + 'text' => esc_html__('Indigo Veil', 'darkify'),
352 + 'swatch' => '#46598c',
353 + 'pro_only' => true,
354 + ),
355 + 'set5' => array(
356 + 'text' => esc_html__('Duskmire', 'darkify'),
357 + 'swatch' => '#403953',
358 + 'pro_only' => true,
359 + ),
360 + 'set7' => array(
361 + 'text' => esc_html__('Tidal Frost', 'darkify'),
362 + 'swatch' => '#286f8d',
363 + 'pro_only' => true,
364 + ),
365 + 'set8' => array(
366 + 'text' => esc_html__('Blue Bastion', 'darkify'),
367 + 'swatch' => '#244892',
368 + 'pro_only' => true,
369 + ),
370 + 'set11' => array(
371 + 'text' => esc_html__('Crimson Veil', 'darkify'),
372 + 'swatch' => '#440649',
373 + 'pro_only' => true,
374 + ),
375 + ),
376 + 'dependency' => array('enable_admin_panel_dark_mode', '==', 'true'),
377 + ),
378 +
379 + array(
427 380 'id' => 'block_editor_dark_mode',
428 381 'type' => 'switcher',
429 382 'title' => esc_html__('Block Editor Dark Mode', 'darkify'),
430 383 'title_help' =>
@@ -430,21 +383,100 @@
430 383 'title_help' =>
431 384 '<div class="darkify-info-label">' .
432 385 __('Enable the dark mode switch in the block editor to toggle between dark and light mode.', 'darkify') .
433 386 '</div>' .
434 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#admin') . '" target="_blank" rel="noopener noreferrer">' .
435 - esc_html__('Live Demo', 'darkify') .
436 - '</a>' .
437 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#admin') . '" target="_blank" rel="noopener noreferrer">' .
438 - esc_html__('Open Docs', 'darkify') .
439 - '</a>',
387 + '' .
388 + '',
440 389 'text_on' => esc_html__('Enabled', 'darkify'),
441 390 'text_off' => esc_html__('Disabled', 'darkify'),
442 - 'default' => true,
391 + 'default' => false,
443 392 'text_width' => 100,
444 - 'dependency' => array('enable_admin_panel_dark_mode', '==', 'true'),
445 393 ),
446 394 array(
395 + 'id' => 'block_editor_palette',
396 + 'type' => 'select',
397 + 'title' => esc_html__('Block Editor Palette', 'darkify'),
398 + 'title_help' =>
399 + '<div class="darkify-info-label">' .
400 + __('Color preset for the block editor, independent of the rest of the admin.', 'darkify') .
401 + '</div>',
402 + 'default' => 'auto',
403 + 'options' => array(
404 + 'auto' => array(
405 + 'text' => esc_html__('Auto (recommended)', 'darkify'),
406 + 'swatch' => 'linear-gradient(135deg, #0f0f0f 0%, #3a3a3a 50%, #8f8f8f 100%)',
407 + ),
408 + 'set1' => array(
409 + 'text' => esc_html__('Carbon Mist', 'darkify'),
410 + 'swatch' => '#171717',
411 + ),
412 + 'set3' => array(
413 + 'text' => esc_html__('Midnight Reverie', 'darkify'),
414 + 'swatch' => '#4e478d',
415 + ),
416 + 'set9' => array(
417 + 'text' => esc_html__('Verdant Depths', 'darkify'),
418 + 'swatch' => '#073d2f',
419 + ),
420 + 'set6' => array(
421 + 'text' => esc_html__('Celestial Tide', 'darkify'),
422 + 'swatch' => '#144e78',
423 + ),
424 + 'set10' => array(
425 + 'text' => esc_html__('Emberwood', 'darkify'),
426 + 'swatch' => '#372911',
427 + ),
428 +
429 + /*
430 + * Pro presets, listed after every one that works here so the
431 + * usable list is not diluted at the top.
432 + *
433 + * These are not new upsell surface. The block editor's toolbar
434 + * dropdown has always offered all eleven names while
435 + * darkify_apply_palette() defines only five, so picking one of
436 + * these silently rendered Carbon Mist — they looked broken
437 + * rather than gated. Marking them is what makes that honest.
438 + *
439 + * `pro_only` is the whole mechanism: locked_option_keys() turns
440 + * it into the `pro_options` stamp the React admin renders as a
441 + * disabled, badged row, and strip_pro_keys() refuses to persist
442 + * the value even if a crafted request sends it.
443 + */
444 + 'set2' => array(
445 + 'text' => esc_html__('Glacier Drift', 'darkify'),
446 + 'swatch' => '#123d52',
447 + 'pro_only' => true,
448 + ),
449 + 'set4' => array(
450 + 'text' => esc_html__('Indigo Veil', 'darkify'),
451 + 'swatch' => '#46598c',
452 + 'pro_only' => true,
453 + ),
454 + 'set5' => array(
455 + 'text' => esc_html__('Duskmire', 'darkify'),
456 + 'swatch' => '#403953',
457 + 'pro_only' => true,
458 + ),
459 + 'set7' => array(
460 + 'text' => esc_html__('Tidal Frost', 'darkify'),
461 + 'swatch' => '#286f8d',
462 + 'pro_only' => true,
463 + ),
464 + 'set8' => array(
465 + 'text' => esc_html__('Blue Bastion', 'darkify'),
466 + 'swatch' => '#244892',
467 + 'pro_only' => true,
468 + ),
469 + 'set11' => array(
470 + 'text' => esc_html__('Crimson Veil', 'darkify'),
471 + 'swatch' => '#440649',
472 + 'pro_only' => true,
473 + ),
474 + ),
475 + 'dependency' => array('block_editor_dark_mode', '==', 'true'),
476 + ),
477 +
478 + array(
447 479 'id' => 'classic_editor_dark_mode',
448 480 'type' => 'switcher',
449 481 'title' => esc_html__('Classic Editor Dark Mode', 'darkify'),
450 482 'title_help' =>
@@ -450,22 +482,25 @@
450 482 'title_help' =>
451 483 '<div class="darkify-info-label">' .
452 484 __('Enable the dark mode switch in the classic editor to toggle between dark and light modes.', 'darkify') .
453 485 '</div>' .
454 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#admin') . '" target="_blank" rel="noopener noreferrer">' .
455 - esc_html__('Live Demo', 'darkify') .
456 - '</a>' .
457 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#admin') . '" target="_blank" rel="noopener noreferrer">' .
458 - esc_html__('Open Docs', 'darkify') .
459 - '</a>',
486 + '' .
487 + '',
460 488 'text_on' => esc_html__('Enabled', 'darkify'),
461 489 'text_off' => esc_html__('Disabled', 'darkify'),
462 490
463 - 'default' => true,
491 + 'default' => false,
464 492 'text_width' => 100,
465 493 ),
466 494
495 + // ===== SCOPE & CUSTOMIZATION =====
467 496 array(
497 + 'type' => 'heading',
498 + 'title' => esc_html__('Scope & Customization', 'darkify'),
499 + 'section_start' => true,
500 + 'dependency' => array('enable_admin_panel_dark_mode', '==', 'true'),
501 + ),
502 + array(
468 503 'id' => 'disallowed_admin_pages',
469 504 'type' => 'textarea',
470 505 'title' => esc_html__('Disallowed Pages', 'darkify'),
471 506 'title_help' => '<div class="darkify-info-text">' .
@@ -470,14 +505,10 @@
470 505 'title' => esc_html__('Disallowed Pages', 'darkify'),
471 506 'title_help' => '<div class="darkify-info-text">' .
472 507 __('If an admin page URL looks like http://example.com/wp-admin/admin.php?page=darkify, then "darkify" is the page slug.', 'darkify') .
473 508 '</div>' .
474 - '<a class="tooltip_btn_primary" href="' . esc_url(DARKIFY_DEMO_URL . 'controls/#admin') . '" target="_blank" rel="noopener noreferrer">' .
475 - esc_html__('Live Demo', 'darkify') .
476 - '</a>' .
477 - '<a class="tooltip_btn_secondary" href="' . esc_url(DARKIFY_DOCS_URL . 'controls/#admin-controls') . '" target="_blank" rel="noopener noreferrer">' .
478 - esc_html__('Open Docs', 'darkify') .
479 - '</a>',
509 + '' .
510 + '',
480 511 'placeholder' => esc_html__('Enter comma-separated page slugs. Example: darkify-dashboard, elementor', 'darkify'),
481 512 'dependency' => array('enable_admin_panel_dark_mode', '==', 'true'),
482 513 'class' => 'only_pro'
483 514 ),
@@ -492,8 +523,10 @@
492 523 'settings' => array(
493 524 'theme' => 'mbo',
494 525 'mode' => 'css',
495 526 ),
527 + // Only relevant when admin dark mode is active — hide it while off.
528 + 'dependency' => array('enable_admin_panel_dark_mode', '==', 'true'),
496 529 ),
497 530 ),
498 531 ),
499 532 ),