this.onChangeComplete( color ) }
/>
diff --git a/core/includes/customizer/extend-controls/src/color/responsive-color-picker-control.js b/core/includes/customizer/extend-controls/src/color/responsive-color-picker-control.js
index f3ea460b3..ae63f9129 100644
--- a/core/includes/customizer/extend-controls/src/color/responsive-color-picker-control.js
+++ b/core/includes/customizer/extend-controls/src/color/responsive-color-picker-control.js
@@ -123,20 +123,17 @@ class ResponsiveColorPickerControl extends Component {
} = this.state;
const getColorPreviewValue = (value, wantRawValue = false) => {
- let color = null;
- if( value && ( value.startsWith('palette') || value.includes('headings-color') ) ) {
- color = 'var(--responsive-global-' + value + ')';
+ if ( value && ( value.startsWith('palette') || value.includes('headings-color') || value.startsWith('title-above-content') ) ) {
+ const varName = value.startsWith('title-above-content') ? `--responsive-${value}` : `--responsive-global-${value}`;
if (wantRawValue) {
- const raw = getComputedStyle(document.documentElement)
- .getPropertyValue('--responsive-global-' + value)
+ return getComputedStyle(document.documentElement)
+ .getPropertyValue(varName)
.trim();
- return raw;
}
- } else {
- color = value;
+ return `var(${varName})`;
}
- return color;
- }
+ return value;
+ };
// Determine the background style based on activeTab
const buttonBackgroundStyle = activeTab === 'gradient' && is_gradient_available
diff --git a/core/includes/customizer/extend-controls/src/color/responsive-color-picker-with-hover-contorl.js b/core/includes/customizer/extend-controls/src/color/responsive-color-picker-with-hover-contorl.js
index 9b94f9ff4..b8ad9470e 100644
--- a/core/includes/customizer/extend-controls/src/color/responsive-color-picker-with-hover-contorl.js
+++ b/core/includes/customizer/extend-controls/src/color/responsive-color-picker-with-hover-contorl.js
@@ -101,20 +101,17 @@ class ResponsiveColorPickerWithHoverControl extends Component {
const { inputattr } = this.state;
const getColorPreviewValue = (value, wantRawValue = false) => {
- let color = null;
- if( value && value.includes('palette') ) {
- color = 'var(--responsive-global-' + value + ')';
+ if ( value && ( value.includes('palette') || value.includes('headings-color') || value.includes('title-above-content') ) ) {
+ const varName = value.includes('title-above-content') ? `--responsive-${value}` : `--responsive-global-${value}`;
if (wantRawValue) {
- const raw = getComputedStyle(document.documentElement)
- .getPropertyValue('--responsive-global-' + value)
+ return getComputedStyle(document.documentElement)
+ .getPropertyValue(varName)
.trim();
- return raw;
}
- } else {
- color = value;
+ return `var(${varName})`;
}
- return color;
- }
+ return value;
+ };
return (
<>
diff --git a/core/includes/customizer/extend-controls/src/customizer.js b/core/includes/customizer/extend-controls/src/customizer.js
index 2e73b9146..413a4cdd9 100644
--- a/core/includes/customizer/extend-controls/src/customizer.js
+++ b/core/includes/customizer/extend-controls/src/customizer.js
@@ -437,6 +437,9 @@
if (typeof value === 'string' && value.startsWith('palette')) {
return `var(--responsive-global-${value})`;
}
+ if (typeof value === 'string' && value.startsWith('title-above-content')) {
+ return `var(--responsive-${value})`;
+ }
return value;
}
@@ -460,6 +463,7 @@
}
});
cssVars['--responsive-global-headings-color'] = processThemeSettingForCSS('responsive_all_heading_text_color');
+ cssVars['--responsive-border-color'] = processThemeSettingForCSS('responsive_border_color');
const root = document.documentElement;
Object.entries(cssVars).forEach(([varName, color]) => {
@@ -476,6 +480,42 @@
// value.bind(applyPalette);
});
+ wp.customize( 'responsive_border_color', function( value ) {
+ value.bind( function( newval ) {
+ if( newval && newval.startsWith('palette') ) {
+ newval = `var(--responsive-global-${newval})`;
+ }
+ document.documentElement.style.setProperty(
+ '--responsive-border-color',
+ newval
+ );
+ });
+ });
+
+ wp.customize( 'responsive_title_above_content_bg_color', function( value ) {
+ value.bind( function( newval ) {
+ if( newval && newval.startsWith('palette') ) {
+ newval = `var(--responsive-global-${newval})`;
+ }
+ document.documentElement.style.setProperty(
+ '--responsive-title-above-content-bg-color',
+ newval
+ );
+ });
+ });
+
+ wp.customize( 'responsive_title_above_content_overlay_color', function( value ) {
+ value.bind( function( newval ) {
+ if( newval && newval.startsWith('palette') ) {
+ newval = `var(--responsive-global-${newval})`;
+ }
+ document.documentElement.style.setProperty(
+ '--responsive-title-above-content-overlay-color',
+ newval
+ );
+ });
+ });
+
wp.customize( 'responsive_all_heading_text_color', function( value ) {
value.bind( function( newval ) {
if( newval && newval.startsWith('palette') ) {
diff --git a/core/includes/customizer/extend-controls/src/index.js b/core/includes/customizer/extend-controls/src/index.js
index 4e8942696..d20684675 100644
--- a/core/includes/customizer/extend-controls/src/index.js
+++ b/core/includes/customizer/extend-controls/src/index.js
@@ -9,6 +9,7 @@ import { responsiveCheckbox } from './checkbox/control';
import { responsivePalette } from './palette/control';
import { responsiveTypography } from './typography/control';
import { responsiveDimensions } from './dimensions/control';
+import { responsiveUnitDimensions } from './unit-dimensions/control';
import { responsiveColor } from './color/control';
import { responsiveColorStates } from './color-states/control';
import { responsiveRedirect} from './redirect/control';
@@ -27,6 +28,7 @@ import { responsiveTypographyGroup } from './typography_group/control';
import { responsiveFontPreset } from './fontpresets/control';
import { responsiveButtonPreset } from './buttonpresets/control';
import './breadcrumb-toggle';
+import './author-box-toggle';
import { responsiveBuilderControl } from './builder-layout/control';
import { responsiveMultiSelectControl } from './multi-select/control';
import { responsiveRangeWithSwitcher } from './range-with-switchers/control';
@@ -53,6 +55,7 @@ wp.customize.controlConstructor['responsive-checkbox'] = responsiveCheckbox;
wp.customize.controlConstructor['responsive-palette'] = responsivePalette;
wp.customize.controlConstructor['responsive-typography'] = responsiveTypography;
wp.customize.controlConstructor['responsive-dimensions'] = responsiveDimensions;
+wp.customize.controlConstructor['responsive-unit-dimensions'] = responsiveUnitDimensions;
wp.customize.controlConstructor['alpha-color'] = responsiveColor;
wp.customize.controlConstructor['alpha-color-states'] = responsiveColorStates;
wp.customize.controlConstructor['responsive-redirect'] = responsiveRedirect;
diff --git a/core/includes/customizer/extend-controls/src/palette/palette-component.js b/core/includes/customizer/extend-controls/src/palette/palette-component.js
index 83d888b60..d3db2a120 100644
--- a/core/includes/customizer/extend-controls/src/palette/palette-component.js
+++ b/core/includes/customizer/extend-controls/src/palette/palette-component.js
@@ -206,15 +206,15 @@ const PaletteComponent = props => {
function getDefaultColor(settingId) {
if(settingId === "responsive_global_color_palette_text_color")
{
- return "#364151";
+ return "#404040";
}
else if(settingId === "responsive_global_color_palette_headings_color")
{
- return "#fcba03";
+ return "#404040";
}
else if(settingId === "responsive_global_color_palette_accent_color")
{
- return "#0066CC";
+ return "#3B82F6";
}
else if(settingId === "responsive_global_color_palette_link_hover_color")
{
@@ -224,10 +224,10 @@ const PaletteComponent = props => {
return "#ffffff";
}
else if(settingId === "responsive_global_color_palette_site_background_color"){
- return "#f0f5fa";
+ return "#f8fafc";
}
else if(settingId === "responsive_global_color_palette_alt_background_color"){
- return "#eaeaea";
+ return "#ffffff";
}
else if(settingId === "responsive_global_color_palette_subtle_background_color"){
return "#007fff";
diff --git a/core/includes/customizer/extend-controls/src/range-with-switchers/range-component.js b/core/includes/customizer/extend-controls/src/range-with-switchers/range-component.js
index 2e9dfdee9..fe96a0864 100644
--- a/core/includes/customizer/extend-controls/src/range-with-switchers/range-component.js
+++ b/core/includes/customizer/extend-controls/src/range-with-switchers/range-component.js
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import {__} from '@wordpress/i18n';
-import {useState} from 'react';
+import {useState, useEffect} from 'react';
const ResponsiveRangeWithSwitchersComponent = props => {
@@ -11,12 +11,39 @@ const ResponsiveRangeWithSwitchersComponent = props => {
link,
inputAttrs,
name,
- desktop,
+ desktop,
tablet,
mobile,
devices = ['desktop', 'tablet', 'mobile'], // Default to all devices for backward compatibility
+ units = [],
} = props.control.params;
+ const [activeUnits, setActiveUnits] = useState({
+ desktop: props_value['desktop_unit'] ? props_value['desktop_unit'].get() : (units[0] || 'px'),
+ tablet: props_value['tablet_unit'] ? props_value['tablet_unit'].get() : (units[0] || 'px'),
+ mobile: props_value['mobile_unit'] ? props_value['mobile_unit'].get() : (units[0] || 'px'),
+ });
+
+ const [dropdownOpen, setDropdownOpen] = useState({
+ desktop: false,
+ tablet: false,
+ mobile: false
+ });
+
+ useEffect(() => {
+ const handleOutsideClick = () => {
+ setDropdownOpen({
+ desktop: false,
+ tablet: false,
+ mobile: false
+ });
+ };
+ document.addEventListener('click', handleOutsideClick);
+ return () => {
+ document.removeEventListener('click', handleOutsideClick);
+ };
+ }, []);
+
let labelHtml = null,
inputHtml = null,
resetHtml = null,
@@ -43,6 +70,8 @@ const ResponsiveRangeWithSwitchersComponent = props => {
});
}
+
+
const updateValues = (device, value ) => {
let inputValue = Number(value);
let updateValue = {...props_value};
@@ -50,7 +79,7 @@ const ResponsiveRangeWithSwitchersComponent = props => {
setPropsValue(updateValue);
};
- if (label) {
+ if (label) {
// Determine which device should be active by default (first device in the array)
const defaultActiveDevice = devices.length > 0 ? devices[0] : 'desktop';
@@ -82,9 +111,9 @@ const ResponsiveRangeWithSwitchersComponent = props => {
;
}
- const renderInputHtml = (device, active = '') => {
+ const renderInputHtml = (device, active = '') => {
let link = (device === 'desktop') ? desktop.link : (device === 'tablet') ? tablet.link : mobile.link;
- if (undefined !== link) {
+ if (undefined !== link) {
let splited_values = link.split("=");
if (undefined !== splited_values[1]) {
link = splited_values[1].replace(/"/g, "");
@@ -94,29 +123,29 @@ const ResponsiveRangeWithSwitchersComponent = props => {
return
updateValues(device, event.target.value)}
style={{
- background: `linear-gradient(to right, #007CBA ${sliderWidth}%, #D9D9D9 ${sliderWidth}%)`
+ background: `linear-gradient(to right, #007CBA ${sliderWidth}%, #D9D9D9 ${sliderWidth}%)`
}}
- />
+ />
updateValues(device, event.target.value)}
- />
+ {...inp_array}
+ type="number"
+ data-name={name}
+ data-customize-setting-link={link}
+ className="responsive-range-switchers-input"
+ value={props_value[`${device}`].get()}
+ onChange={(event) => updateValues(device, event.target.value)}
+ />
;
};
- const renderResetHtml = (device, active = '') => {
+ const renderResetHtml = (device, active = '') => {
return
;
- }
+ };
+
+ const renderUnitSelector = (device, active = '') => {
+ if (units.length === 0) return null;
+
+ const currentUnit = activeUnits[device];
- // Determine which device should be active by default (first device in the array)
+ return (
+
+
+ {dropdownOpen[device] && (
+
+ {units.map((unit) => (
+ - {
+ e.preventDefault();
+ e.stopPropagation();
+ setActiveUnits(prev => ({ ...prev, [device]: unit }));
+ if (props_value[`${device}_unit`]) {
+ props_value[`${device}_unit`].set(unit);
+ }
+ setDropdownOpen(prev => ({
+ ...prev,
+ [device]: false
+ }));
+ }}
+ >
+ {unit.toLowerCase()}
+
+ ))}
+
+ )}
+
+ );
+ };
+
+ // Determine which device should be active by default (first device in the array)
const defaultActiveDevice = devices.length > 0 ? devices[0] : 'desktop';
inputHtml = <>
@@ -147,18 +227,25 @@ const ResponsiveRangeWithSwitchersComponent = props => {
{devices.includes('tablet') && renderInputHtml('tablet', defaultActiveDevice === 'tablet' ? 'active' : '')}
{devices.includes('mobile') && renderInputHtml('mobile', defaultActiveDevice === 'mobile' ? 'active' : '')}
>;
- resetHtml = <>
- {devices.includes('desktop') && renderResetHtml('desktop', defaultActiveDevice === 'desktop' ? 'active' : '')}
- {devices.includes('tablet') && renderResetHtml('tablet', defaultActiveDevice === 'tablet' ? 'active' : '')}
- {devices.includes('mobile') && renderResetHtml('mobile', defaultActiveDevice === 'mobile' ? 'active' : '')}
- >
+ resetHtml = <>
+ {devices.includes('desktop') && renderResetHtml('desktop', defaultActiveDevice === 'desktop' ? 'active' : '')}
+ {devices.includes('tablet') && renderResetHtml('tablet', defaultActiveDevice === 'tablet' ? 'active' : '')}
+ {devices.includes('mobile') && renderResetHtml('mobile', defaultActiveDevice === 'mobile' ? 'active' : '')}
+ >;
return
-
- {labelHtml}
- {resetHtml}
-
- {inputHtml}
+
+ {labelHtml}
+ {units.length > 0 && (
+
+ {devices.includes('desktop') && renderUnitSelector('desktop', defaultActiveDevice === 'desktop' ? 'active' : '')}
+ {devices.includes('tablet') && renderUnitSelector('tablet', defaultActiveDevice === 'tablet' ? 'active' : '')}
+ {devices.includes('mobile') && renderUnitSelector('mobile', defaultActiveDevice === 'mobile' ? 'active' : '')}
+
+ )}
+ {resetHtml}
+
+ {inputHtml}
;
};
diff --git a/core/includes/customizer/extend-controls/src/sortable/control.js b/core/includes/customizer/extend-controls/src/sortable/control.js
index 5ea53d880..f5ca4f76e 100644
--- a/core/includes/customizer/extend-controls/src/sortable/control.js
+++ b/core/includes/customizer/extend-controls/src/sortable/control.js
@@ -41,6 +41,17 @@ export const responsiveSortable = wp.customize.responsiveControl.extend( {
// Update value on click.
control.updateValue();
});
+
+ // Sub-controls logic handled in React now
+ let subControls = control.params.sub_controls || {};
+ console.log('Sortable Control Init:', control.id, 'Sub-controls mapping:', subControls);
+
+ // Handle chevron click for dropdown
+ control.sortableContainer.find('.responsive-sortable-chevron').click(function(e) {
+ e.stopPropagation(); // prevent drag or visibility toggle from capturing this
+ jQuery(this).toggleClass('expanded');
+ jQuery(this).closest('li').find('.responsive-sortable-dropdown').slideToggle();
+ });
},
/**
diff --git a/core/includes/customizer/extend-controls/src/sortable/sortable-component.js b/core/includes/customizer/extend-controls/src/sortable/sortable-component.js
index ca689df59..e16930007 100644
--- a/core/includes/customizer/extend-controls/src/sortable/sortable-component.js
+++ b/core/includes/customizer/extend-controls/src/sortable/sortable-component.js
@@ -1,4 +1,225 @@
import PropTypes from 'prop-types';
+import ResponsiveSliderComponent from '../slider/slider-component.js';
+
+const SubControls = ({ choiceID, subControlIds }) => {
+ if (choiceID === 'author' && subControlIds && subControlIds.length >= 3) {
+ const prefixSettingId = subControlIds[0];
+ const avatarSettingId = subControlIds[1];
+ const sizeSettingId = subControlIds[2];
+
+ const [prefixLabel, setPrefixLabel] = React.useState((wp.customize(prefixSettingId) && wp.customize(prefixSettingId).get()) || 'By');
+ const [authorAvatar, setAuthorAvatar] = React.useState((wp.customize(avatarSettingId) && wp.customize(avatarSettingId).get()) || false);
+
+ // Mock control for ResponsiveSliderComponent
+ const mockSliderControl = {
+ id: sizeSettingId,
+ setting: {
+ get: () => {
+ const val = wp.customize(sizeSettingId) ? wp.customize(sizeSettingId).get() : null;
+ return val || 30;
+ },
+ set: (val) => {
+ if (wp.customize(sizeSettingId)) {
+ wp.customize(sizeSettingId).set(val);
+ }
+ }
+ },
+ params: {
+ label: 'Image Size',
+ default: 30,
+ inputAttrs: 'min="10" max="100" step="1"'
+ }
+ };
+
+ React.useEffect(() => {
+ const prefixSetting = wp.customize(prefixSettingId);
+ if (prefixSetting) prefixSetting.bind(setPrefixLabel);
+
+ const avatarSetting = wp.customize(avatarSettingId);
+ if (avatarSetting) avatarSetting.bind(setAuthorAvatar);
+
+ return () => {
+ if (prefixSetting) prefixSetting.unbind(setPrefixLabel);
+ if (avatarSetting) avatarSetting.unbind(setAuthorAvatar);
+ };
+ }, [prefixSettingId, avatarSettingId]);
+
+ const handlePrefixChange = (e) => {
+ const val = e.target.value;
+ setPrefixLabel(val);
+ if (wp.customize(prefixSettingId)) {
+ wp.customize(prefixSettingId).set(val);
+ }
+ };
+
+ const handleAvatarChange = (e) => {
+ const val = e.target.checked;
+ setAuthorAvatar(val);
+ if (wp.customize(avatarSettingId)) {
+ wp.customize(avatarSettingId).set(val);
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+ {authorAvatar && (
+
+
+
+ )}
+
+ );
+ }
+
+ if ((choiceID === 'date' || choiceID === 'updated') && subControlIds && subControlIds.length >= 1) {
+ const formatSettingId = subControlIds[0];
+ const [dateFormat, setDateFormat] = React.useState((wp.customize(formatSettingId) && wp.customize(formatSettingId).get()) || 'default');
+
+ React.useEffect(() => {
+ const formatSetting = wp.customize(formatSettingId);
+ if (formatSetting) formatSetting.bind(setDateFormat);
+ return () => {
+ if (formatSetting) formatSetting.unbind(setDateFormat);
+ };
+ }, [formatSettingId]);
+
+ const handleFormatChange = (e) => {
+ const val = e.target.value;
+ setDateFormat(val);
+ if (wp.customize(formatSettingId)) {
+ wp.customize(formatSettingId).set(val);
+ }
+ };
+
+ const labelText = choiceID === 'updated' ? 'Last Updated Format' : 'Date Format';
+
+ return (
+
+
+
+
+
+ );
+ }
+
+
+ if ((choiceID === 'categories' || choiceID === 'tag') && subControlIds && subControlIds.length >= 1) {
+ const styleSettingId = subControlIds[0];
+ const [style, setStyle] = React.useState((wp.customize(styleSettingId) && wp.customize(styleSettingId).get()) || 'default');
+
+ React.useEffect(() => {
+ const styleSetting = wp.customize(styleSettingId);
+ if (styleSetting) styleSetting.bind(setStyle);
+ return () => {
+ if (styleSetting) styleSetting.unbind(setStyle);
+ };
+ }, [styleSettingId]);
+
+ const handleStyleChange = (val) => {
+ setStyle(val);
+ if (wp.customize(styleSettingId)) {
+ wp.customize(styleSettingId).set(val);
+ }
+ };
+
+ return (
+
+
+
Style
+
+ {['default', 'badge', 'underline'].map((opt) => (
+
+ ))}
+
+
+
+ );
+ }
+ if (choiceID === 'meta' && subControlIds && subControlIds.length >= 1) {
+ const dividerSettingId = subControlIds[0];
+ const [divider, setDivider] = React.useState((wp.customize(dividerSettingId) && wp.customize(dividerSettingId).get()) || '•');
+
+ React.useEffect(() => {
+ const dividerSetting = wp.customize(dividerSettingId);
+ if (dividerSetting) dividerSetting.bind(setDivider);
+ return () => {
+ if (dividerSetting) dividerSetting.unbind(setDivider);
+ };
+ }, [dividerSettingId]);
+
+ const handleDividerChange = (val) => {
+ setDivider(val);
+ if (wp.customize(dividerSettingId)) {
+ wp.customize(dividerSettingId).set(val);
+ }
+ };
+
+ return (
+
+
+
Divider Type
+
+ {['/', '-', '|', '•', 'None'].map((opt) => (
+
+ ))}
+
+
+
+ );
+ }
+
+ return ;
+};
const SortableComponent = props => {
@@ -10,7 +231,8 @@ const SortableComponent = props => {
description,
value,
choices,
- inputAttrs
+ inputAttrs,
+ sub_controls
} = props.control.params;
if (label) {
@@ -24,17 +246,42 @@ const SortableComponent = props => {
let visibleMetaHtml = Object.values(value).map(choiceID => {
let html = '';
if (choices[choiceID]) {
- html =
- ', $pos, 6 );
+ } else {
+ $link .= $edit_link;
+ }
+ }
+ return $link;
+}
\ No newline at end of file
diff --git a/loop-header.php b/loop-header.php
index 497e05be7..871485d4c 100644
--- a/loop-header.php
+++ b/loop-header.php
@@ -96,28 +96,96 @@
if ( ! $responsive_page_title && ! $responsive_page_description && ! $responsive_show_breadcrumbs ) {
return;
}
+
+$is_blog_archive = ( is_home() || ( is_archive() && ! is_search() ) );
+$blog_layout = get_theme_mod( 'responsive_blog_title_layout', 'post_title_layout1' );
+
+if ( $is_blog_archive ) {
+ if ( 'post_title_layout2' === $blog_layout ) {
+ // Output is handled in responsive_wrapper_top hook
+ return;
+ }
+
+ $elements = get_theme_mod( 'responsive_blog_title_elements_positioning', array( 'title', 'description', 'breadcrumb' ) );
+ if ( is_string( $elements ) ) {
+ $decoded = json_decode( $elements, true );
+ $elements = is_array( $decoded ) ? $decoded : explode( ',', $elements );
+ } else if ( ! is_array( $elements ) ) {
+ $elements = array();
+ }
+
+ // For layout1:
+ // Hide everything on the blog page.
+ if ( is_home() ) {
+ $responsive_page_title = '';
+ $responsive_page_description = '';
+ $responsive_show_breadcrumbs = false;
+ } else {
+ // For archive pages, conditionally show elements based on their presence in the control.
+ if ( ! in_array( 'breadcrumb', $elements, true ) ) {
+ $responsive_show_breadcrumbs = false;
+ } else {
+ $responsive_show_breadcrumbs = true;
+ }
+ if ( ! in_array( 'title', $elements, true ) ) {
+ $responsive_page_title = '';
+ }
+ if ( ! in_array( 'description', $elements, true ) ) {
+ $responsive_page_description = '';
+ }
+ }
+
+ if ( ! $responsive_page_title && ! $responsive_page_description && ! $responsive_show_breadcrumbs ) {
+ return;
+ }
+}
?>