You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

65 lines
1.6 KiB

import React, { useEffect, useRef } from 'react'
interface UseStyleOptions {
selector?: string;
styles: React.CSSProperties & { [key: `--${string}`]: string };
}
const applyStyles = (element: HTMLElement, styles: React.CSSProperties) => {
Object.entries(styles).forEach(([ key, value ]) => {
element.style.setProperty(key, value as string)
})
}
const removeStyles = (element: HTMLElement, styles: React.CSSProperties) => {
Object.keys(styles).forEach(key => {
element.style.removeProperty(key)
})
}
function useInlineStyle({ selector, styles }: UseStyleOptions) {
const elementRef = useRef<HTMLElement | null>(null)
useEffect(() => {
let targetElement: HTMLElement | null = null
const manageStyles = () => {
targetElement = selector ? document.querySelector<HTMLElement>(selector) : elementRef.current
if (!targetElement) return
applyStyles(targetElement, styles)
return () => {
if (targetElement) {
removeStyles(targetElement, styles)
}
}
}
if (selector) {
if (document.readyState === 'complete' || document.readyState === 'interactive') {
manageStyles()
} else {
document.addEventListener('DOMContentLoaded', manageStyles)
return () => {
document.removeEventListener('DOMContentLoaded', manageStyles)
}
}
} else {
manageStyles()
}
return () => {
if (targetElement) {
removeStyles(targetElement, styles)
}
}
}, [ selector, styles ])
return elementRef
}
export default useInlineStyle