| 1 |
/** |
| 2 |
* @param styles {object} - { base: { shared: '', variant: { shared: '', h1: '', h2: '' } }, dark: { shared: '', variant: { shared: '', h1: '', h2: '' } } } |
| 3 |
* @param config {object} - { variants: { light: true, dark: false } } |
| 4 |
* @param props {object} - { variant: 'h1', size: 'xl' } |
| 5 |
* @param type {string} - shared/unique (in case that only the shared/unique styles are needed) |
| 6 |
* @returns {string} - 'background-color: #000; color: #fff;' |
| 7 |
*/ |
| 8 |
export const getStyle = ( styles, props, type ) => { |
| 9 |
if ( ! styles ) { |
| 10 |
return ''; |
| 11 |
} |
| 12 |
|
| 13 |
if ( 'string' === typeof styles ) { |
| 14 |
return styles; |
| 15 |
} |
| 16 |
|
| 17 |
const config = props?.theme?.config || { variants: {} }, |
| 18 |
style = { |
| 19 |
shared: '', |
| 20 |
unique: '', |
| 21 |
}; |
| 22 |
|
| 23 |
// Creating an array that holds only the active theme variants values. |
| 24 |
const themeVariants = Object.keys( config.variants ).filter( ( key ) => config.variants[ key ] ), |
| 25 |
addStyle = ( data, keys = [] ) => { |
| 26 |
if ( 'string' === typeof data && 'unique' !== type ) { |
| 27 |
style.shared += data; |
| 28 |
|
| 29 |
return; |
| 30 |
} |
| 31 |
|
| 32 |
Object.values( keys ).map( ( key ) => { |
| 33 |
const styleObjKey = 'shared' !== key ? 'unique' : 'shared'; |
| 34 |
|
| 35 |
if ( ! type || styleObjKey === type ) { |
| 36 |
style[ styleObjKey ] += data[ key ] || ''; |
| 37 |
} |
| 38 |
} ); |
| 39 |
}; |
| 40 |
|
| 41 |
// Adding the 'base' key, to be included as the first variant. |
| 42 |
themeVariants.unshift( 'base' ); |
| 43 |
|
| 44 |
themeVariants.forEach( ( key ) => { |
| 45 |
const themeVariant = styles[ key ]; |
| 46 |
|
| 47 |
// If key exist in the styles obj (dark, light etc.) |
| 48 |
if ( themeVariant ) { |
| 49 |
addStyle( themeVariant, [ 'shared' ] ); |
| 50 |
|
| 51 |
const styledProps = getStyledProps( props ); |
| 52 |
|
| 53 |
// Getting the styled props css from the styles object. |
| 54 |
Object.entries( styledProps ).forEach( ( [ propName, propValue ] ) => { |
| 55 |
const styleData = themeVariant[ propName ]; |
| 56 |
|
| 57 |
if ( styleData && propValue ) { |
| 58 |
addStyle( styleData, [ 'shared', propValue ] ); |
| 59 |
} |
| 60 |
} ); |
| 61 |
} |
| 62 |
} ); |
| 63 |
|
| 64 |
// Both properties are returned but their values are depended on the third argument of this function, if empty: both will be calculated. |
| 65 |
return style.shared + style.unique; |
| 66 |
}; |
| 67 |
|
| 68 |
const getStyledProps = ( props ) => { |
| 69 |
const styledProps = { ...props }; |
| 70 |
|
| 71 |
// Removing props names that are not related to the styles objects. |
| 72 |
[ 'className', 'children', 'tag', 'as', 'theme' ].forEach( ( prop ) => delete styledProps[ prop ] ); |
| 73 |
|
| 74 |
return styledProps; |
| 75 |
}; |
| 76 |
|