16 changed files with 349 additions and 122 deletions
			
			
		- 
					4src/App.css
 - 
					14src/components/avatar/index.tsx
 - 
					2src/components/loading/FetchLoading.tsx
 - 
					2src/components/table/style.ts
 - 
					2src/global.d.ts
 - 
					65src/hooks/useInlineStyle.ts
 - 
					63src/hooks/useResizeObserver.ts
 - 
					20src/layout/ListPageLayout.tsx
 - 
					27src/layout/RootLayout.tsx
 - 
					21src/layout/TwoColPageLayout.tsx
 - 
					21src/layout/style.ts
 - 
					8src/pages/system/menus/index.tsx
 - 
					5src/pages/websites/domain/index.tsx
 - 
					5src/store/system.ts
 - 
					203src/store/system/user.ts
 - 
					9src/utils/index.ts
 
@ -0,0 +1,65 @@ | 
				
			|||
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 | 
				
			|||
@ -0,0 +1,63 @@ | 
				
			|||
import { useState, useEffect, useRef } from 'react' | 
				
			|||
 | 
				
			|||
interface UseResizeObserverOptions { | 
				
			|||
  selector?: string; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
interface Size { | 
				
			|||
  width: number; | 
				
			|||
  height: number; | 
				
			|||
  inlineSize: number; | 
				
			|||
  blockSize: number; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
function useResizeObserver({ selector }: UseResizeObserverOptions = {}) { | 
				
			|||
  const [ size, setSize ] = useState<Size>({ width: 0, height: 0, inlineSize: 0, blockSize: 0 }) | 
				
			|||
  const elementRef = useRef<HTMLElement | null>(null) | 
				
			|||
 | 
				
			|||
  useEffect(() => { | 
				
			|||
    const handleResize = (entries: ResizeObserverEntry[]) => { | 
				
			|||
      if (entries[0]) { | 
				
			|||
        const [ { inlineSize, blockSize } ] = entries[0].borderBoxSize | 
				
			|||
        const { width, height } = entries[0].contentRect | 
				
			|||
        setSize({ width, height, inlineSize, blockSize }) | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    let resizeObserver: ResizeObserver | null = null | 
				
			|||
    let targetElement: HTMLElement | null = null | 
				
			|||
 | 
				
			|||
    const observeElement = () => { | 
				
			|||
      targetElement = selector ? document.querySelector<HTMLElement>(selector) : elementRef.current | 
				
			|||
 | 
				
			|||
      if (!targetElement) return | 
				
			|||
 | 
				
			|||
      resizeObserver = new ResizeObserver(handleResize) | 
				
			|||
      resizeObserver.observe(targetElement) | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    if (selector) { | 
				
			|||
      if (document.readyState === 'complete' || document.readyState === 'interactive') { | 
				
			|||
        observeElement() | 
				
			|||
      } else { | 
				
			|||
        document.addEventListener('DOMContentLoaded', observeElement) | 
				
			|||
        return () => { | 
				
			|||
          document.removeEventListener('DOMContentLoaded', observeElement) | 
				
			|||
        } | 
				
			|||
      } | 
				
			|||
    } else { | 
				
			|||
      observeElement() | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    return () => { | 
				
			|||
      if (resizeObserver && targetElement) { | 
				
			|||
        resizeObserver.unobserve(targetElement) | 
				
			|||
        resizeObserver.disconnect() | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
  }, [ selector, elementRef.current ]) | 
				
			|||
 | 
				
			|||
  return [ elementRef, size ] as const | 
				
			|||
} | 
				
			|||
 | 
				
			|||
export default useResizeObserver | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue