kodadot/nft-gallery

View on GitHub
composables/useTheme.ts

Summary

Maintainability
B
4 hrs
Test Coverage
type COLOR_MODE = 'system' | 'light' | 'dark'

const IMG_PLACEHOLDER_LIGHT = '/Klight.webp'
const IMG_PLACEHOLDER_DARK = '/Kdark.webp'
export const IMG_PLACEHOLDERS = [IMG_PLACEHOLDER_LIGHT, IMG_PLACEHOLDER_DARK]

export default function () {
  const colorMode = useColorMode()
  const { $i18n } = useNuxtApp()

  const isDarkMode = computed<boolean>(() => colorMode.value === 'dark')
  const isSystemMode = computed<boolean>(
    () => colorMode.preference === 'system',
  )

  const themeOptions = computed<
    { value: COLOR_MODE, icon: string, label: string }[]
  >(() => [
    {
      value: 'system',
      icon: 'computer-classic',
      label: isSystemMode.value
        ? $i18n.t('profileMenu.systemMode', [
          isDarkMode.value
            ? $i18n.t('profileMenu.dark')
            : $i18n.t('profileMenu.light'),
        ])
        : $i18n.t('profileMenu.system'),
    },
    {
      value: 'light',
      icon: 'sun',
      label: $i18n.t('profileMenu.lightMode'),
    },
    {
      value: 'dark',
      icon: 'moon',
      label: $i18n.t('profileMenu.darkMode'),
    },
  ])

  const currentModeIndex = computed(() =>
    themeOptions.value.findIndex(option => option.value === preference.value),
  )

  const currentMode = computed(
    () => themeOptions.value[currentModeIndex.value || 0],
  )

  const switchToNextMode = () => {
    const nextIndex = (currentModeIndex.value + 1) % themeOptions.value.length
    setColorMode(themeOptions.value[nextIndex].value)
  }

  const toggleColorMode = (): void => {
    if (colorMode.value === 'dark') {
      colorMode.preference = 'light'
    }
    else {
      colorMode.preference = 'dark'
    }
  }

  const preference = computed(() => colorMode.preference)

  const placeholder = computed(() => {
    return isDarkMode.value ? IMG_PLACEHOLDER_DARK : IMG_PLACEHOLDER_LIGHT
  })

  const setColorMode = (mode: 'light' | 'dark' | 'system') => {
    colorMode.preference = mode
  }

  return {
    themeOptions,
    currentMode,
    switchToNextMode,
    currentModeIndex,
    isDarkMode,
    isSystemMode,
    setColorMode,
    isLightMode: computed(() => !isDarkMode.value),
    preference,
    toggleColorMode,
    placeholder,
  }
}