{"version":3,"file":"dark-mode.cjs","sources":["../src/dark-mode.ts"],"sourcesContent":["export function init(options: {\n  toggle?: Element | null;\n  classes?: { dark: string, light: string };\n  default?: string;\n  storageKey?: string;\n  onInit?: (toggle?: Element | null) => unknown;\n  onUserToggle?: (toggle?: Element | null) => unknown;\n  onChange?: (theme: string, toggle?: Element | null) => unknown;\n}): void {\n  options = options || {};\n\n  // use a specified element(s) to trigger swap when clicked\n  const toggle = options.toggle || null;\n\n  // check for preset `dark_mode_pref` preference in local storage\n  const storageKey = options.storageKey || \"dark_mode_pref\";\n  const pref = localStorage.getItem(storageKey);\n\n  // change CSS via these <body> classes:\n  const dark = options.classes ? options.classes.dark : \"dark\";\n  const light = options.classes ? options.classes.light : \"light\";\n\n  // which class is <body> set to initially?\n  const defaultTheme = options.default || \"light\";\n\n  // keep track of current state no matter how we got there\n  let active = defaultTheme === dark;\n\n  // receives a class name and switches <body> to it\n  const activateTheme = function (theme: string, remember?: boolean) {\n    // optional onChange callback function passed as option\n    if (typeof options.onChange === \"function\") {\n      options.onChange(theme, toggle);\n    }\n\n    document.body.classList.remove(dark, light);\n    document.body.classList.add(theme);\n    active = theme === dark;\n\n    if (remember) {\n      localStorage.setItem(storageKey, theme);\n    }\n  };\n\n  // optional onInit callback function passed as option\n  if (typeof options.onInit === \"function\") {\n    options.onInit(toggle);\n  }\n\n  // user has never clicked the button, so go by their OS preference until/if they do so\n  if (!pref) {\n    // returns media query selector syntax\n    const prefers = function (colorScheme: \"dark\" | \"light\") {\n      // https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme\n      return `(prefers-color-scheme: ${colorScheme})`;\n    };\n\n    // check for OS dark/light mode preference and switch accordingly\n    // default to `defaultTheme` set above if unsupported\n    if (window.matchMedia(prefers(\"dark\")).matches) {\n      activateTheme(dark);\n    } else if (window.matchMedia(prefers(\"light\")).matches) {\n      activateTheme(light);\n    } else {\n      activateTheme(defaultTheme);\n    }\n\n    // real-time switching if supported by OS/browser\n    window.matchMedia(prefers(\"dark\")).addEventListener(\"change\", function (e) {\n      if (e.matches) {\n        activateTheme(dark);\n      }\n    });\n    window.matchMedia(prefers(\"light\")).addEventListener(\"change\", function (e) {\n      if (e.matches) {\n        activateTheme(light);\n      }\n    });\n  } else if (pref === dark || pref === light) {\n    // if user already explicitly toggled in the past, restore their preference\n    activateTheme(pref);\n  } else {\n    // fallback to default theme (this shouldn't happen)\n    activateTheme(defaultTheme);\n  }\n\n  // don't freak out if page happens not to have a toggle\n  if (toggle !== null) {\n    // handle toggle click\n    toggle.addEventListener(\"click\", function () {\n      // optional onUserToggle callback function passed as option\n      if (typeof options.onUserToggle === \"function\") {\n        options.onUserToggle(toggle);\n      }\n\n      // switch to the opposite theme & save preference in local storage\n      if (active) {\n        activateTheme(light, true);\n      } else {\n        activateTheme(dark, true);\n      }\n    });\n  }\n}\n"],"names":["options","toggle","storageKey","pref","localStorage","getItem","dark","classes","light","defaultTheme","active","activateTheme","theme","remember","onChange","document","body","classList","remove","add","setItem","onInit","prefers","colorScheme","window","matchMedia","matches","addEventListener","e","onUserToggle"],"mappings":"sBAAqBA,GAYnB,IAAMC,GAHND,EAAUA,GAAW,IAGEC,QAAU,KAG3BC,EAAaF,EAAQE,YAAc,iBACnCC,EAAOC,aAAaC,QAAQH,GAG5BI,EAAON,EAAQO,QAAUP,EAAQO,QAAQD,KAAO,OAChDE,EAAQR,EAAQO,QAAUP,EAAQO,QAAQC,MAAQ,QAGlDC,EAAeT,WAAmB,QAGpCU,EAASD,IAAiBH,EAGxBK,EAAgB,SAAUC,EAAeC,GAEb,mBAArBb,EAAQc,UACjBd,EAAQc,SAASF,EAAOX,GAG1Bc,SAASC,KAAKC,UAAUC,OAAOZ,EAAME,GACrCO,SAASC,KAAKC,UAAUE,IAAIP,GAC5BF,EAASE,IAAUN,EAEfO,GACFT,aAAagB,QAAQlB,EAAYU,IAUrC,GAL8B,mBAAnBZ,EAAQqB,QACjBrB,EAAQqB,OAAOpB,GAIZE,EA8BHQ,EAFSR,IAASG,GAAQH,IAASK,EAErBL,EAGAM,OAjCL,CAET,IAAMa,EAAU,SAAUC,GAExB,gCAAiCA,OAK/BC,OAAOC,WAAWH,EAAQ,SAASI,QACrCf,EAAcL,GACLkB,OAAOC,WAAWH,EAAQ,UAAUI,QAC7Cf,EAAcH,GAEdG,EAAcF,GAIhBe,OAAOC,WAAWH,EAAQ,SAASK,iBAAiB,SAAU,SAAUC,GAClEA,EAAEF,SACJf,EAAcL,KAGlBkB,OAAOC,WAAWH,EAAQ,UAAUK,iBAAiB,SAAU,SAAUC,GACnEA,EAAEF,SACJf,EAAcH,KAYL,OAAXP,GAEFA,EAAO0B,iBAAiB,QAAS,WAEK,mBAAzB3B,EAAQ6B,cACjB7B,EAAQ6B,aAAa5B,GAKrBU,EADED,EACYF,EAEAF,GAFO"}