import { useEffect , useRef } from 'react' ; import uniqueId from 'lodash.uniqueid' ; param selector param theme param customClass return const setComponentTheme = < T > ( selector , theme , customClass ) : void => { if ( typeof window === 'undefined' ) return ; const hasCustomRule = ( rule ) : boolean => rule . selectorText ?. includes ( `${ selector }.${ customClass }` ) ; try { let parentIndex = [ ... document . styleSheets ] . findIndex ( ( styleSheet ) => { try { return [ ... styleSheet . cssRules ] . findIndex ( ( rule ) => rule . selectorText ?. includes ( selector ) ) >= 0 ; } catch ( e ) { return false ; } } ) ; if ( parentIndex === - 1 ) { const stylesheetElement = document . createElement ( 'style' ) ; document . head . appendChild ( stylesheetElement ) ; parentIndex = document . styleSheets . length - 1 ; } const parentStyleSheet = document . styleSheets [ parentIndex ] ; const parentCssRules = parentStyleSheet . cssRules ; let customRuleIndex = [ ... parentCssRules ] . findIndex ( hasCustomRule ) ; if ( customRuleIndex === - 1 ) { parentStyleSheet . insertRule ( `.${ selector }.${ customClass } { content: '' }` , parentCssRules . length ) ; customRuleIndex = [ ... parentCssRules ] . findIndex ( hasCustomRule ) ; } const rule = parentCssRules . item ( customRuleIndex ) as CSSStyleRule ; Object . entries ( theme ) . forEach ( ( [ property , value ] ) => rule . style . setProperty ( property , value ) ) ; } catch ( e ) { console . warn ( `Could not find the stylesheet to update with the "${ selector }" selector!` ) ; } } ; param selector param theme return { string } export const useTheme = < T > ( selector , theme ) : string => { const useCustomTheme = theme && typeof theme !== 'string' ; const customClass = useRef < string > ( useCustomTheme ? uniqueId ( 'custom-theme-' ) : '' ) . current ; useEffect ( ( ) => { if ( useCustomTheme ) setComponentTheme < T > ( selector , theme , customClass ) ; } , [ selector , theme , customClass , useCustomTheme ] ) ; return customClass ; } ;