| 1 |
import { useEffect } from '@wordpress/element'; |
| 2 |
|
| 3 |
import { generateProperty } from '../helpers'; |
| 4 |
|
| 5 |
export const StyleTag = ({ casecadeStyles, deviceType }) => { |
| 6 |
return ( |
| 7 |
<style> |
| 8 |
{casecadeStyles?.desktop ?? ''} |
| 9 |
{casecadeStyles?.desktopHover ?? ''} |
| 10 |
{casecadeStyles?.extraStyles ?? ''} |
| 11 |
{deviceType === 'Tablet' && (casecadeStyles?.tab ?? '')} |
| 12 |
{deviceType === 'Tablet' && (casecadeStyles?.tabHover ?? '')} |
| 13 |
{deviceType === 'Mobile' && (casecadeStyles?.mobile ?? '')} |
| 14 |
{deviceType === 'Mobile' && (casecadeStyles?.mobileHover ?? '')} |
| 15 |
|
| 16 |
{ |
| 17 |
casecadeStyles?.tab?.length != 0 && |
| 18 |
`@media all and (max-width: 1024px) { |
| 19 |
${casecadeStyles?.tab ?? ''} |
| 20 |
${casecadeStyles?.tabHover ?? ''} |
| 21 |
}` |
| 22 |
} |
| 23 |
{ |
| 24 |
casecadeStyles?.mobile?.length != 0 && |
| 25 |
`@media all and (max-width: 767px) { |
| 26 |
${casecadeStyles?.mobile ?? ''} |
| 27 |
${casecadeStyles?.mobileHover ?? ''} |
| 28 |
}` |
| 29 |
} |
| 30 |
</style> |
| 31 |
) |
| 32 |
}; |
| 33 |
|
| 34 |
const setDeviceTypeCSS = (cssStore, selectors, styles) => { |
| 35 |
cssStore[selectors] = [...(cssStore[selectors] || []), styles]; |
| 36 |
return cssStore; |
| 37 |
}; |
| 38 |
|
| 39 |
const useStyleSheets = (props) => { |
| 40 |
const { properties: propertiesArgs = [], setAttributes, attributes } = props; |
| 41 |
const deviceType = attributes?.resOption; |
| 42 |
|
| 43 |
const properties = propertiesArgs.reduce((prev, propertyArg) => { |
| 44 |
const property = generateProperty(propertyArg, attributes); |
| 45 |
prev[property.id] = property; |
| 46 |
|
| 47 |
return prev; |
| 48 |
}, {}); |
| 49 |
|
| 50 |
const htmlAttributes = Object.values(properties) |
| 51 |
.filter(property => property?.attr) |
| 52 |
.map(property => property.htmlAttrs) |
| 53 |
.reduce((prev, value) => ({ ...prev, ...value }), {}); |
| 54 |
|
| 55 |
const casecadeStylesObject = Object.values(properties) |
| 56 |
.filter(property => property.cssSelector !== undefined) |
| 57 |
.reduce((previous, property) => { |
| 58 |
const propertyCSS = property.getCssStrings(); |
| 59 |
const hoverSelector = property?.hoverSelector != undefined ? property?.hoverSelector : `${property.cssSelector}:hover`; |
| 60 |
|
| 61 |
setDeviceTypeCSS(previous.desktop, property.cssSelector, propertyCSS?.desktop); |
| 62 |
setDeviceTypeCSS(previous.desktopHover, hoverSelector, propertyCSS?.desktopHover); |
| 63 |
setDeviceTypeCSS(previous.tab, property.cssSelector, propertyCSS?.tab); |
| 64 |
setDeviceTypeCSS(previous.tabHover, hoverSelector, propertyCSS?.tabHover); |
| 65 |
setDeviceTypeCSS(previous.mobile, property.cssSelector, propertyCSS?.mobile); |
| 66 |
setDeviceTypeCSS(previous.mobileHover, hoverSelector, propertyCSS?.mobileHover); |
| 67 |
|
| 68 |
const stylesProperty = property.getStylesProperty(); |
| 69 |
|
| 70 |
if (Object.keys(stylesProperty).length > 0) { |
| 71 |
Object.entries(stylesProperty).forEach(([selector, css]) => { |
| 72 |
previous.extraStyles[selector] = previous.extraStyles[selector] || {}; |
| 73 |
Object.entries(css).forEach(([property, styles]) => { |
| 74 |
previous.extraStyles[selector][property] = [...(previous.extraStyles[selector][property] || []), ...styles]; |
| 75 |
}); |
| 76 |
}); |
| 77 |
} |
| 78 |
|
| 79 |
return previous; |
| 80 |
}, { desktop: {}, tab: {}, mobile: {}, desktopHover: {}, tabHover: {}, mobileHover: {}, extraStyles: {} }); |
| 81 |
|
| 82 |
const casecadeStyles = Object.keys(casecadeStylesObject).reduce((prev, deviceType) => { |
| 83 |
if (deviceType === 'extraStyles') { |
| 84 |
const extraStyles = Object.entries(casecadeStylesObject[deviceType]).reduce((prevValue, [selector, styles]) => { |
| 85 |
const cssStyles = Object.entries(styles).reduce((prev, [p, value]) => { |
| 86 |
return prev + `${p}:${value.join(', ')};`; |
| 87 |
}, ''); |
| 88 |
return `${prevValue} ${selector}{ ${cssStyles} }`; |
| 89 |
}, ''); |
| 90 |
return { ...prev, [deviceType]: extraStyles }; |
| 91 |
} else { |
| 92 |
const deviceStyles = Object.entries(casecadeStylesObject[deviceType]).map(([selector, value]) => { |
| 93 |
value = value.filter( item => item != undefined && item != null && item.trim() != '' ); |
| 94 |
return value?.length > 0 ? { [selector]: value.join('') } : {}; |
| 95 |
}).reduce((allCss, item) => { |
| 96 |
return allCss + Object.entries(item).reduce((prev, [selector, cssProps]) => { |
| 97 |
return prev + `${selector}{ ${cssProps} }`; |
| 98 |
}, ''); |
| 99 |
}, ''); |
| 100 |
return { ...prev, [deviceType]: deviceStyles }; |
| 101 |
} |
| 102 |
}, {}); |
| 103 |
|
| 104 |
useEffect(() => { |
| 105 |
if (JSON.stringify(attributes?.blockMeta) != JSON.stringify(casecadeStyles)) { |
| 106 |
setAttributes({ blockMeta: casecadeStyles }); |
| 107 |
} |
| 108 |
}, [attributes]); |
| 109 |
|
| 110 |
return { |
| 111 |
properties, |
| 112 |
htmlAttributes, |
| 113 |
casecadeStyles, |
| 114 |
styleTag: () => <StyleTag casecadeStyles={casecadeStyles} deviceType={deviceType} /> |
| 115 |
}; |
| 116 |
} |
| 117 |
|
| 118 |
export default useStyleSheets |
| 119 |
|