iterative/vscode-dvc

View on GitHub
webview/src/shared/components/webviewWrapper/useThemeVariables.ts

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
import { useState, useLayoutEffect, useCallback } from 'react'
import { alphaToHex, getThemeValue, ThemeProperty } from '../../../util/styles'

export const useThemeVariables = () => {
  const [variables, setVariables] = useState<Record<string, string>>({})

  const createCSSVariables = useCallback(() => {
    const ColorsWithOpacity = {
      accent: getThemeValue(ThemeProperty.ACCENT_COLOR),
      'editor-background': getThemeValue(ThemeProperty.BACKGROUND_COLOR),
      'editor-foreground': getThemeValue(ThemeProperty.FOREGROUND_COLOR)
    }

    type ColorsWithOpacityKey = keyof typeof ColorsWithOpacity

    const variables: { [key: string]: string } = {}
    for (const key in ColorsWithOpacity) {
      for (let i = 1; i < 10; i++) {
        variables[`--${key}-transparency-${i}`] = alphaToHex(
          ColorsWithOpacity[key as ColorsWithOpacityKey],
          i / 10
        )
      }
    }

    setVariables(variables)
  }, [])

  const createObserver = useCallback(() => {
    const targetNode = document.documentElement
    const config = { attributes: true, childList: false, subtree: false }
    const callback = () => createCSSVariables()
    const observer = new MutationObserver(callback)

    observer.observe(targetNode, config)

    return observer
  }, [createCSSVariables])

  useLayoutEffect(() => {
    createCSSVariables()
    const observer = createObserver()
    return () => {
      observer.disconnect()
    }
  }, [createCSSVariables, createObserver])

  return variables
}