{
  "mappings": "AAGA,YAAY,WAAW;AAOvB,cAAc,0BAAyC;AAEvD,OAAO,cAAM,mBAAmB,MAAM,kBAAkB",
  "names": [],
  "sources": [
    "src/NextThemeProvider.tsx"
  ],
  "version": 3,
  "sourcesContent": [
    "import { useIsomorphicLayoutEffect } from '@tamagui/constants'\nimport { useEvent } from '@tamagui/use-event'\nimport Script from 'next/script'\nimport * as React from 'react'\nimport { memo, useEffect, useMemo, useState } from 'react'\n\nimport { MEDIA, colorSchemes } from './constants'\nimport { getSystemTheme, getTheme } from './helpers'\nimport { ThemeSettingContext } from './ThemeSettingContext'\nimport type { ValueObject } from './types'\nimport type { ThemeProviderProps, UseThemeProps } from './UseThemeProps'\n\nexport const NextThemeProvider: React.FunctionComponent<ThemeProviderProps> = memo(\n  ({\n    forcedTheme,\n    disableTransitionOnChange = false,\n    enableSystem = true,\n    enableColorScheme = true,\n    storageKey = 'theme',\n    themes = colorSchemes,\n    defaultTheme = enableSystem ? 'system' : 'light',\n    attribute = 'class',\n    skipNextHead,\n    onChangeTheme,\n    value = {\n      dark: 't_dark',\n      light: 't_light',\n    },\n    children,\n  }) => {\n    const [theme, setThemeState] = useState(() => getTheme(storageKey, defaultTheme))\n    const [resolvedTheme, setResolvedTheme] = useState(() => getTheme(storageKey))\n    const attrs = !value ? themes : Object.values(value)\n\n    const handleMediaQuery = useEvent((e?) => {\n      const _ = getSystemTheme(e)\n      const update = () => setResolvedTheme(_)\n      if (disableTransitionOnChange) {\n        update()\n      } else {\n        React.startTransition(() => update())\n      }\n      if (theme === 'system' && !forcedTheme) {\n        handleChangeTheme(_, false)\n      }\n    })\n\n    const handleChangeTheme = useEvent(\n      (theme, updateStorage = true, updateDOM = true) => {\n        let name = value?.[theme] || theme\n\n        if (updateStorage) {\n          try {\n            localStorage.setItem(storageKey, theme)\n          } catch (e) {\n            // Unsupported\n          }\n        }\n\n        if (theme === 'system' && enableSystem) {\n          const resolved = getSystemTheme()\n          name = value?.[resolved] || resolved\n        }\n\n        onChangeTheme?.(name.replace('t_', ''))\n\n        if (updateDOM) {\n          const d = document.documentElement\n          if (attribute === 'class') {\n            d.classList.remove(...attrs)\n            d.classList.add(name)\n          } else {\n            d.setAttribute(attribute, name)\n          }\n        }\n      }\n    )\n\n    useIsomorphicLayoutEffect(() => {\n      // Always listen to System preference\n      const media = window.matchMedia(MEDIA)\n      // Intentionally use deprecated listener methods to support iOS & old browsers\n      media.addListener(handleMediaQuery)\n      handleMediaQuery(media)\n      return () => {\n        media.removeListener(handleMediaQuery)\n      }\n    }, [])\n\n    const set = useEvent((newTheme) => {\n      if (forcedTheme) {\n        // when forcedTheme is active, block all updates to avoid desync\n        return\n      }\n      handleChangeTheme(newTheme)\n      setThemeState(newTheme)\n    })\n\n    // localStorage event handling\n    useEffect(() => {\n      const handleStorage = (e: StorageEvent) => {\n        if (e.key !== storageKey) {\n          return\n        }\n        // If default theme set, use it if localstorage === null (happens on local storage manual deletion)\n        const theme = e.newValue || defaultTheme\n        set(theme)\n      }\n      window.addEventListener('storage', handleStorage)\n      return () => {\n        window.removeEventListener('storage', handleStorage)\n      }\n    }, [defaultTheme, set, storageKey])\n\n    // color-scheme handling\n    useIsomorphicLayoutEffect(() => {\n      if (!enableColorScheme) return\n\n      const colorScheme =\n        // If theme is forced to light or dark, use that\n        forcedTheme && colorSchemes.includes(forcedTheme as 'light' | 'dark')\n          ? forcedTheme\n          : // If regular theme is light or dark\n            theme && colorSchemes.includes(theme)\n            ? theme\n            : // If theme is system, use the resolved version\n              theme === 'system'\n              ? resolvedTheme || null\n              : null\n\n      // color-scheme tells browser how to render built-in elements like forms, scrollbars, etc.\n      // if color-scheme is null, this will remove the property\n      const userPrefers =\n        typeof window !== 'undefined' &&\n        window.matchMedia &&\n        window.matchMedia('(prefers-color-scheme: dark)').matches\n          ? 'dark'\n          : 'light'\n\n      const wePrefer = colorScheme || 'light'\n\n      // avoid running this because it causes full page reflow\n      if (userPrefers !== wePrefer) {\n        document.documentElement.style.setProperty('color-scheme', colorScheme)\n      }\n    }, [enableColorScheme, theme, resolvedTheme, forcedTheme])\n\n    const toggle = useEvent(() => {\n      const order =\n        resolvedTheme === 'dark'\n          ? ['system', 'light', 'dark']\n          : ['system', 'dark', 'light']\n      const next = order[(order.indexOf(theme) + 1) % order.length]\n      set(next)\n    })\n\n    const systemTheme = (enableSystem ? resolvedTheme : undefined) as\n      | 'light'\n      | 'dark'\n      | undefined\n\n    const contextValue = useMemo(() => {\n      const value: UseThemeProps = {\n        theme,\n        current: theme,\n        set,\n        toggle,\n        forcedTheme,\n        resolvedTheme: theme === 'system' ? resolvedTheme : theme,\n        themes: enableSystem ? [...themes, 'system'] : (themes as string[]),\n        systemTheme,\n      } as const\n      return value\n    }, [\n      theme,\n      set,\n      toggle,\n      forcedTheme,\n      resolvedTheme,\n      enableSystem,\n      themes,\n      systemTheme,\n    ])\n\n    return (\n      <ThemeSettingContext.Provider value={contextValue}>\n        <ThemeScript\n          {...{\n            forcedTheme,\n            storageKey,\n            systemTheme: resolvedTheme,\n            attribute,\n            value,\n            enableSystem,\n            defaultTheme,\n            attrs,\n            skipNextHead,\n          }}\n        />\n        {children}\n      </ThemeSettingContext.Provider>\n    )\n  }\n)\n\nconst ThemeScript = memo(\n  ({\n    forcedTheme,\n    storageKey,\n    attribute,\n    enableSystem,\n    defaultTheme,\n    value,\n    attrs,\n    skipNextHead,\n  }: {\n    forcedTheme?: string\n    storageKey: string\n    attribute?: string\n    enableSystem?: boolean\n    defaultTheme: string\n    value?: ValueObject\n    attrs: any\n    skipNextHead?: boolean\n  }) => {\n    // Code-golfing the amount of characters in the script\n    const optimization = (() => {\n      if (attribute === 'class') {\n        const removeClasses = attrs.map((t: string) => `d.remove('${t}')`).join(';')\n        return `var d=document.documentElement.classList;${removeClasses};`\n      }\n      return `var d=document.documentElement;`\n    })()\n\n    const updateDOM = (name: string, literal?: boolean) => {\n      name = value?.[name] || name\n      const val = literal ? name : `'${name}'`\n\n      if (attribute === 'class') {\n        return `d.add(${val})`\n      }\n\n      return `d.setAttribute('${attribute}', ${val})`\n    }\n\n    const defaultSystem = defaultTheme === 'system'\n\n    const scriptContent = forcedTheme\n      ? `!function(){${optimization}${updateDOM(forcedTheme)}}()`\n      : enableSystem\n        ? `!function(){try {${optimization}var e=localStorage.getItem('${storageKey}');if(\"system\"===e||(!e&&${defaultSystem})){var t=\"${MEDIA}\",m=window.matchMedia(t);m.media!==t||m.matches?${updateDOM(\n            'dark'\n          )}:${updateDOM('light')}}else if(e){${\n            value ? `var x=${JSON.stringify(value)};` : ''\n          }${updateDOM(value ? 'x[e]' : 'e', true)}}${\n            !defaultSystem ? `else{${updateDOM(defaultTheme)}}` : ''\n          }}catch(e){}}()`\n        : `!function(){try{${optimization}var e=localStorage.getItem(\"${storageKey}\");if(e){${\n            value ? `var x=${JSON.stringify(value)};` : ''\n          }${updateDOM(value ? 'x[e]' : 'e', true)}}else{${updateDOM(\n            defaultTheme\n          )};}}catch(t){}}();`\n\n    // skipNextHead returns raw script for useServerInsertedHTML usage\n    if (skipNextHead) {\n      return (\n        <script\n          key=\"next-themes-script\"\n          dangerouslySetInnerHTML={{ __html: scriptContent }}\n        />\n      )\n    }\n\n    return (\n      <Script\n        id=\"next-themes-script\"\n        strategy=\"beforeInteractive\"\n        dangerouslySetInnerHTML={{ __html: scriptContent }}\n      />\n    )\n  },\n  (prevProps, nextProps) => {\n    // Only re-render when forcedTheme changes\n    // the rest of the props should be completely stable\n    if (prevProps.forcedTheme !== nextProps.forcedTheme) return false\n    return true\n  }\n)\n"
  ]
}