Your IP : 3.145.196.141
import { __ } from '@wordpress/i18n';
import { LabelControl } from './label';
import { useState, useRef, useEffect } from '@wordpress/element';
import { RenderScreenIcons } from './screen-icon';
const { pagelayer_fonts } = pagelayer_config;
// TODO: imporve this for global
// TODO load Font Family
export const TypoControl = (props) => {
const { attributes, prop, label, value, setAttributes, deviceType } = props;
const { name } = prop['c'];
const typoRef = useRef(null);
const globalRef = useRef(null);
const globalIconRef = useRef(null);
const [isTypoVisible, setTypoVisible] = useState(false);
const [isGlobalVisible, setGlobalVisible] = useState(false);
const [isGLobalTypo, setGLobalTypo] = useState(pagelayerIsGlobalTypo(value));
const modes = { desktop: '', tablet: '_tablet', mobile: '_mobile' };
var values = pagelayerParseTypo(value, false);
var tabValue = pagelayerParseTypo(attributes[name+'_tablet']);
var mobValue = pagelayerParseTypo(attributes[name+'_mobile']);
// Convert the jQuery function to a React method
const handleInputChange = (e) => {
var jEle = jQuery(e.target);
if(jQuery(e.target).attr('name') == 'font-family' ){
pagelayer_link_font_family(jQuery(e.target));
}
jEle.closest('[pagelayer-set-global]').removeAttr('pagelayer-set-global');
// Set attributes
handleSaveTypo();
};
// Convert the jQuery function to a React method
const handleSaveTypo = () => {
if(!isTypoVisible){
return;
}
const atts = {};
atts[name] = {};
atts[name + '_tablet'] = {};
atts[name + '_mobile'] = {};
if(!pagelayer_empty(isGLobalTypo)){
atts[name]['global-font'] = isGLobalTypo;
}
const inputElements = typoRef.current.querySelectorAll('.pagelayer-elp-typo-input');
inputElements.forEach((iEle) => {
const eName = iEle.getAttribute('name');
const value = iEle.value;
const isGlobal = jQuery(iEle).closest('[pagelayer-set-global]');
if((value == '' && isGlobal.length < 1 && pagelayer_empty(isGLobalTypo)) || isGlobal.length > 0){
return;
}
if(pagelayer_empty(value)){
return;
}
if (eName.indexOf('_tablet') > -1) {
const modifiedName = eName.replace('_tablet', '');
atts[name + '_tablet'][modifiedName] = value;
} else if (eName.indexOf('_mobile') > -1) {
const modifiedName = eName.replace('_mobile', '');
atts[name + '_mobile'][modifiedName] = value;
} else {
atts[name][eName] = value;
}
});
// Set attributes
setAttributes(atts);
};
const onClickGlobalTypo = (e, globalTypo) => {
e.stopPropagation();
var row = jQuery(typoRef.current);
setGlobalVisible(false);
if(isGLobalTypo == globalTypo){
row.find('[pagelayer-set-global]').removeAttr('pagelayer-set-global');
setGLobalTypo('');
return;
}
setGLobalTypo(globalTypo);
var fontSelect = row.find('.pagelayer-elp-typo-input[name="font-family"]');
// Set global value to all fields and save
row.find('.pagelayer-elp-label .pagelayer-typo-default').each(function(){
restoreGlobalHandler(jQuery(this), true, globalTypo);
});
pagelayer_link_font_family(fontSelect); // Apply google fonts
}
const openCustomizer = (e) => {
e.stopPropagation();
window.open(pagelayer_customizer_url+'&autofocus%5Bsection%5D=pagelayer_global_fonts_sec', '_blank');
};
useEffect(() => {
handleSaveTypo();
}, [isGLobalTypo]);
useEffect(() => {
var row = jQuery(typoRef.current);
row.on('click', '.pagelayer-typo-default', function(e, skip_save){
restoreGlobalHandler(jQuery(e.target), skip_save);
});
// Active global typography
if(!pagelayer_empty(isGLobalTypo)){
// Show the global values if is not customize
row.find('.pagelayer-elp-typo').attr('pagelayer-set-global', 1);
row.find('.pagelayer-elp-typo').find('select, input').each(function(){
var sEle = jQuery(this);
var val = sEle.val();
if(pagelayer_empty(val)){
return true;
}
sEle.closest('.pagelayer-elp-typo').removeAttr('pagelayer-set-global');
});
row.find('[pagelayer-set-global="1"] .pagelayer-typo-default').trigger('click', [true]);
}
return (() => {
row.unbind('click', '.pagelayer-typo-default');
});
}, [isTypoVisible]);
useEffect(() => {
const handleDocumentClick = (e) => {
// Shodow Modal Handler
if(
typoRef.current &&
!typoRef.current.contains(e.target)
){
setTypoVisible(false);
}
if(
globalRef.current &&
!globalRef.current.contains(e.target) &&
globalIconRef.current &&
!globalIconRef.current.contains(e.target)
){
setGlobalVisible(false);
}
};
document.addEventListener('click', handleDocumentClick);
return () => {
document.removeEventListener('click', handleDocumentClick);
};
}, []);
var save_timer;
const restoreGlobalHandler = (label, skipSave, globalTypo = null) => {
skipSave = skipSave || false;
globalTypo = globalTypo || isGLobalTypo;
if (pagelayer_empty(globalTypo) || !pagelayer_global_fonts[globalTypo]) {
return;
}
const setFonts = pagelayer_global_fonts[globalTypo]['value'];
const holder = label.closest('.pagelayer-elp-typo');
const inputs = holder.find('.pagelayer-elp-typo-input');
const name = inputs.first().attr('name');
let val = '';
holder.attr('pagelayer-set-global', 1);
if (name in setFonts) {
val = setFonts[name];
}
if (typeof val === 'object') {
for (const mode in modes) {
let _val = '';
if (mode in val) {
_val = val[mode];
}
holder.find('.pagelayer-elp-typo-input[name="' + name + modes[mode] + '"]').val(_val);
}
} else {
if (inputs.length > 1) {
inputs.val('');
}
inputs.first().val(val);
}
if (skipSave) {
return;
}
// save value
clearTimeout(save_timer);
save_timer = setTimeout(handleSaveTypo, 200);
}
const RenderLabel = (props) => {
return (
<label {...props}>
{ props.children }
<span
className="pagelayer-typo-default"
title={ __('Restore Global') }
>
<i className="fas fa-undo"></i>
</span>
</label>
);
}
const selectOptions = {
'style': { '': 'Default', 'normal': 'Normal', 'italic': 'Italic', 'oblique': 'Oblique' },
'weight': { '': 'Default', '100': '100', '200': '200', '300': '300', '400': '400', '500': '500', '600': '600', '700': '700', '800': '800', '900': '900', 'normal': 'Normal', 'lighter': 'Lighter', 'bold': 'Bold', 'bolder': 'Bolder', 'unset': 'Unset' },
'variant': { '': 'Default', 'normal': 'Normal', 'small-caps': 'Small Caps' },
'deco-line': { '': 'Default', 'none': 'None', 'overline': 'Overline', 'line-through': 'Line Through', 'underline': 'Underline', 'underline overline': 'Underline Overline' },
'deco-style': { '': 'Default', 'solid': 'Solid', 'double': 'Double', 'dotted': 'Dotted', 'dashed': 'Dashed', 'wavy': 'Wavy' },
'transform': { '': 'Default', 'capitalize': 'Capitalize', 'uppercase': 'Uppercase', 'lowercase': 'Lowercase' },
'fonts': pagelayer_fonts,
}
const createOption = (value = '', lang, setVal = '') => {
const selected = value.toLowerCase() === setVal.toLowerCase();
const displayLang = lang || 'Default';
return <option value={value} selected={selected}>{displayLang}</option>;
};
const createSelect = (name, options, setVal, attrs) => {
attrs = attrs || {};
return (<select name={name} className="pagelayer-elp-typo-input pagelayer-elp-select" onChange={handleInputChange} {...attrs} >
{Object.keys(options).map((optionVal) => {
return createOption(optionVal, options[optionVal], setVal);
})}
</select>);
};
const fontOptions = [];
const createFontOption = (val, lang, type, setVal) => {
const selected = val !== setVal ? '' : 'selected="selected"';
const displayLang = lang || 'Default';
return (
<option
className="pagelayer-elp-typo-sele-op"
value={val}
type={type}
selected={selected}
>
{displayLang}
</option>
);
};
for(const y in selectOptions['fonts']){
if (y !== 'default') {
fontOptions.push(<optgroup label={pagelayerUcwords(y)} />);
}
for (const x in selectOptions['fonts'][y]) {
fontOptions.push(
createFontOption(
jQuery.isNumeric(x) ? selectOptions['fonts'][y][x] : x,
selectOptions['fonts'][y][x],
y,
values[0]
)
);
}
}
return (
<div className="components-base-control pagelayer-base-control">
<LabelControl {...props} />
<div className={`pagelayer-prop-holder ${ isGLobalTypo ? 'pagelayer-global-on' : ''}`} ref={typoRef}>
<span
className="pagelayer-prop-edit"
onClick={() => setTypoVisible(!isTypoVisible)}
>
<i className="pli pli-pencil"></i>
</span>
{ isTypoVisible && <div className="pagelayer-elp-typo-div" pagelayer-screen-mode={deviceType}>
<div className="pagelayer-elp-global-typo">
<label className="pagelayer-elp-label">{ __('Global Fonts') }</label>
<span className="pagelayer-elp-typo-icons">
<span
className={`pagelayer-elp-global-icon ${ isGLobalTypo ? 'pagelayer-active-global' : ''}`}
onClick={ () => setGlobalVisible(!isGlobalVisible) }
ref={globalIconRef}
></span>
<span className="pli pli-service" onClick={openCustomizer}></span>
</span>
{ isGlobalVisible && (
<div className="pagelayer-global-font-list" ref={globalRef}>
{Object.keys(pagelayer_global_fonts).map((y) => {
return (
<div
className={`pagelayer-global-font-list-item ${ y == isGLobalTypo ? 'pagelayer-global-selected' : ''}`}
data-global-id={y}
onClick={ (e) => onClickGlobalTypo(e, y) }
>
<span className="pagelayer-global-font-title">{pagelayer_global_fonts[y]['title']}</span>
</div>
);
})}
</div>
)}
</div>
<div className="pagelayer-elp-typo">
<RenderLabel className="pagelayer-elp-label">{ __('Font Family') }</RenderLabel>
<select className="pagelayer-elp-typo-input pagelayer-elp-select" name="font-family" onChange={handleInputChange} >{ fontOptions }</select>
</div>
<div className="pagelayer-elp-typo">
<RenderLabel className="pagelayer-elp-label">
{ __('Font Size') }
<RenderScreenIcons {...props} />
</RenderLabel>
<input
className="pagelayer-elp-typo-input"
type="number"
max="200"
min="0"
step="1"
name="font-size"
pagelayer-show-device="desktop"
value={values[1]}
onChange={handleInputChange}
/>
<input
className="pagelayer-elp-typo-input"
type="number"
max="200"
min="0"
step="1"
name="font-size_tablet"
pagelayer-show-device="tablet"
value={tabValue[1]}
onChange={handleInputChange}
/>
<input
className="pagelayer-elp-typo-input"
type="number"
max="200"
min="0"
step="1"
name="font-size_mobile"
pagelayer-show-device="mobile"
value={mobValue[1]}
onChange={handleInputChange}
/>
</div>
<div className="pagelayer-elp-typo">
<RenderLabel className="pagelayer-elp-label">{ __('Font Style') }</RenderLabel>
{createSelect('font-style', selectOptions['style'], values[2])}
</div>
<div className="pagelayer-elp-typo">
<RenderLabel className="pagelayer-elp-label">
{ __('Font Weight') }
<RenderScreenIcons {...props} />
</RenderLabel>
{createSelect('font-weight', selectOptions['weight'], values[3], { 'pagelayer-show-device': 'desktop' } )}
{createSelect('font-weight_tablet', selectOptions['weight'], tabValue[3], { 'pagelayer-show-device': 'tablet' })}
{createSelect('font-weight_mobile', selectOptions['weight'], mobValue[3], { 'pagelayer-show-device': 'mobile' })}
</div>
<div className="pagelayer-elp-typo">
<RenderLabel className="pagelayer-elp-label">{ __('Font Variant') }</RenderLabel>
{createSelect("font-variant", selectOptions['variant'], values[4])}
</div>
<div className="pagelayer-elp-typo">
<RenderLabel className="pagelayer-elp-label">{ __('Decoration Line') }</RenderLabel>
{createSelect('text-decoration-line', selectOptions['deco-line'], values[5])}
</div>
<div className="pagelayer-elp-typo">
<RenderLabel className="pagelayer-elp-label">{ __('Decoration Style') }</RenderLabel>
{createSelect('text-decoration-style', selectOptions['deco-style'], values[6])}
</div>
<div className="pagelayer-elp-typo">
<RenderLabel className="pagelayer-elp-label">
{ __('Line Height') }
<RenderScreenIcons {...props} />
</RenderLabel>
<input
className="pagelayer-elp-typo-input"
type="number"
min="0"
max="100"
step="0.1"
name="line-height"
pagelayer-show-device="desktop"
value={values[7]}
onChange={handleInputChange}
/>
<input
className="pagelayer-elp-typo-input"
type="number"
min="0"
max="100"
step="0.1"
name="line-height_tablet"
pagelayer-show-device="tablet"
value={tabValue[7]}
onChange={handleInputChange}
/>
<input
className="pagelayer-elp-typo-input"
type="number"
min="0"
max="100"
step="0.1"
name="line-height_mobile"
pagelayer-show-device="mobile"
value={mobValue[7]}
onChange={handleInputChange}
/>
</div>
<div className="pagelayer-elp-typo" >
<RenderLabel className="pagelayer-elp-label">{ __('Text Transform') }</RenderLabel>
{createSelect('text-transform', selectOptions['transform'], values[8])}
</div>
<div className="pagelayer-elp-typo">
<RenderLabel className="pagelayer-elp-label">
{ __('Letter Spacing') }
<RenderScreenIcons {...props} />
</RenderLabel>
<input
className="pagelayer-elp-typo-input"
type="number"
min="0"
max="100"
step="0.1"
name="letter-spacing"
pagelayer-show-device="desktop"
value={values[9]}
onChange={handleInputChange}
/>
<input
className="pagelayer-elp-typo-input"
type="number"
min="0"
max="100"
step="0.1"
name="letter-spacing_tablet"
pagelayer-show-device="tablet"
value={tabValue[9]}
onChange={handleInputChange}
/>
<input
className="pagelayer-elp-typo-input"
type="number"
min="0"
max="100"
step="0.1"
name="letter-spacing_mobile"
pagelayer-show-device="mobile"
value={mobValue[9]}
onChange={handleInputChange}
/>
</div>
<div className="pagelayer-elp-typo">
<RenderLabel className="pagelayer-elp-label">
{ __('Word Spacing') }
<RenderScreenIcons {...props} />
</RenderLabel>
<input
className="pagelayer-elp-typo-input"
type="number"
min="0"
max="50"
step="0.1"
name="word-spacing"
pagelayer-show-device="desktop"
value={values[10]}
onChange={handleInputChange}
/>
<input
className="pagelayer-elp-typo-input"
type="number"
min="0"
max="50"
step="0.1"
name="word-spacing_tablet"
pagelayer-show-device="tablet"
value={tabValue[10]}
onChange={handleInputChange}
/>
<input
className="pagelayer-elp-typo-input"
type="number"
min="0"
max="50"
step="0.1"
name="word-spacing_mobile"
pagelayer-show-device="mobile"
value={mobValue[10]}
onChange={handleInputChange}
/>
</div>
</div>
}
</div>
</div>
);
}
// Link font family
export const pagelayer_link_font_family = (sEle) => {
var value = sEle.val();
if(!value || value == 'Default'){
return;
}
value = value.replace(' ', '+');
var t = sEle.find("option:selected").attr('type');
switch(t){
case 'google':
if(pagelayer_query('#pagelayer-google-fonts').length == 0){
if(value==''){
return;
}
pagelayer_query('head').append('<link id="pagelayer-google-fonts" href="https://fonts.googleapis.com/css?family='+value+':100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">');
}else{
var url = pagelayer_query('#pagelayer-google-fonts').attr('href');
if(url.indexOf(value) == -1){
url = url+'|'+value+':100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i';
pagelayer_query('#pagelayer-google-fonts').attr('href', url);
}
}
break;
case 'custom':
if(!pagelayer_empty(pagelayer_query('style[id='+value+'_plf]').length)){
break;
}
jQuery.ajax({
url: pagelayer_ajax_url+'&action=pagelayer_custom_font',
type: 'POST',
dataType: 'json',
data: {
'pagelayer_nonce': pagelayer_ajax_nonce,
'font_name': value
},
success: function(data) {
if('style' in data){
pagelayer_query('body').append(data['style']);
}
}
});
break;
}
}