UNPKG

vanilla-theme

Version:

A small library to quickly add a light and dark mode functionality in you Vanilla JavaScript application

8 lines (7 loc) 5.84 kB
{ "version": 3, "sources": ["../src/index.ts"], "sourcesContent": ["type Theme = \"dark\" | \"light\" | \"system\";\r\ntype Storage = \"localStorage\" | \"sessionStorage\";\r\n\r\nlet storage: Storage = \"localStorage\";\r\nlet default_theme: Theme = \"system\";\r\nlet attribute: \"class\" | \"data-theme\" = \"class\";\r\nlet color_scheme: boolean = true;\r\nlet aborter: undefined | AbortController = undefined;\r\nconst subscribers: Map<number, (theme: Theme) => void> = new Map();\r\nlet subscribers_length = 0;\r\n\r\nconst media_query = window.matchMedia(\"(prefers-color-scheme: dark)\");\r\n\r\nexport function subscribe_to_theme_changes(subscriber: (theme: Theme) => void) {\r\n const id = subscribers_length++;\r\n\r\n subscribers.set(id, subscriber);\r\n\r\n return () => {\r\n subscribers.delete(id);\r\n subscribers_length--;\r\n };\r\n}\r\n\r\nfunction update(theme: Theme) {\r\n for (const subscriber of subscribers.values()) {\r\n subscriber(theme);\r\n }\r\n}\r\n\r\nfunction set_theme() {\r\n const html = document.documentElement;\r\n const class_list = html.classList;\r\n let stored_theme: undefined | null | string;\r\n\r\n if (aborter) {\r\n aborter.abort();\r\n aborter = undefined;\r\n }\r\n\r\n if (attribute == \"class\") {\r\n class_list.remove(\"dark\", \"light\");\r\n }\r\n\r\n if (storage == \"localStorage\") {\r\n stored_theme = localStorage.getItem(\"theme\");\r\n } else if (storage == \"sessionStorage\") {\r\n stored_theme = sessionStorage.getItem(\"theme\");\r\n }\r\n\r\n if (stored_theme == null || (stored_theme != \"dark\" && stored_theme != \"light\" && stored_theme != \"system\")) {\r\n stored_theme = default_theme;\r\n }\r\n\r\n if (stored_theme == \"dark\" || stored_theme == \"light\") {\r\n if (attribute == \"class\") {\r\n class_list.add(stored_theme);\r\n } else {\r\n html.setAttribute(\"data-theme\", stored_theme);\r\n }\r\n\r\n if (color_scheme) {\r\n html.style.colorScheme = stored_theme;\r\n }\r\n\r\n update(stored_theme);\r\n } else {\r\n if (media_query.matches) {\r\n if (attribute == \"class\") {\r\n class_list.add(\"dark\");\r\n } else {\r\n html.setAttribute(\"data-theme\", \"dark\");\r\n }\r\n \r\n if (color_scheme) {\r\n html.style.colorScheme = \"dark\";\r\n }\r\n\r\n update(\"light\");\r\n } else {\r\n if (attribute == \"class\") {\r\n class_list.add(\"light\");\r\n } else {\r\n html.setAttribute(\"data-theme\", \"light\");\r\n }\r\n \r\n if (color_scheme) {\r\n html.style.colorScheme = \"light\";\r\n }\r\n\r\n update(\"dark\");\r\n }\r\n \r\n aborter = new AbortController();\r\n\r\n media_query.addEventListener(\"change\", set_theme, { once: true, signal: aborter.signal });\r\n }\r\n};\r\n\r\n/** Changes the theme to either\r\n * \r\n * - `light`\r\n * - `dark`\r\n * - `system`\r\n * \r\n * If an invalid value is provided, defaults to the default you provide or \"system\".\r\n */\r\nexport function change_theme(theme: Theme) {\r\n switch(storage) {\r\n case \"localStorage\":\r\n localStorage.setItem(\"theme\", theme);\r\n break;\r\n case \"sessionStorage\":\r\n sessionStorage.setItem(\"theme\", theme);\r\n break;\r\n }\r\n\r\n set_theme();\r\n}\r\n\r\nexport function set_storage(setStorage: \"localStorage\" | \"sessionStorage\") {\r\n storage = setStorage;\r\n}\r\n\r\n/** The default fallback if a value is neither dark, light, nor system. */\r\nexport function set_default(defaultTheme: Theme) {\r\n default_theme = defaultTheme;\r\n}\r\n\r\nwindow.addEventListener(\"DOMContentLoaded\", set_theme);\r\n"], "mappings": "+EAGA,IAAIA,EAAmB,eACnBC,EAAuB,SACvBC,EAAoC,QACpCC,EAAwB,GACxBC,EACEC,EAAmD,IAAI,IACzDC,EAAqB,EAEnBC,EAAc,OAAO,WAAW,8BAA8B,EAE7D,SAASC,EAA2BC,EAAoC,CAC3E,IAAMC,EAAKJ,IAEX,OAAAD,EAAY,IAAIK,EAAID,CAAU,EAEvB,IAAM,CACTJ,EAAY,OAAOK,CAAE,EACrBJ,GACJ,CACJ,CATgBK,EAAAH,EAAA,8BAWhB,SAASI,EAAOC,EAAc,CAC1B,QAAWJ,KAAcJ,EAAY,OAAO,EACxCI,EAAWI,CAAK,CAExB,CAJSF,EAAAC,EAAA,UAMT,SAASE,GAAY,CACjB,IAAMC,EAAO,SAAS,gBAChBC,EAAaD,EAAK,UACpBE,EAEAb,IACAA,EAAQ,MAAM,EACdA,EAAU,QAGVF,GAAa,SACbc,EAAW,OAAO,OAAQ,OAAO,EAGjChB,GAAW,eACXiB,EAAe,aAAa,QAAQ,OAAO,EACpCjB,GAAW,mBAClBiB,EAAe,eAAe,QAAQ,OAAO,IAG7CA,GAAgB,MAASA,GAAgB,QAAUA,GAAgB,SAAWA,GAAgB,YAC9FA,EAAehB,GAGfgB,GAAgB,QAAUA,GAAgB,SACtCf,GAAa,QACbc,EAAW,IAAIC,CAAY,EAE3BF,EAAK,aAAa,aAAcE,CAAY,EAG5Cd,IACAY,EAAK,MAAM,YAAcE,GAG7BL,EAAOK,CAAY,IAEfV,EAAY,SACRL,GAAa,QACbc,EAAW,IAAI,MAAM,EAErBD,EAAK,aAAa,aAAc,MAAM,EAGtCZ,IACAY,EAAK,MAAM,YAAc,QAG7BH,EAAO,OAAO,IAEVV,GAAa,QACbc,EAAW,IAAI,OAAO,EAEtBD,EAAK,aAAa,aAAc,OAAO,EAGvCZ,IACAY,EAAK,MAAM,YAAc,SAG7BH,EAAO,MAAM,GAGjBR,EAAU,IAAI,gBAEdG,EAAY,iBAAiB,SAAUO,EAAW,CAAE,KAAM,GAAM,OAAQV,EAAQ,MAAO,CAAC,EAEhG,CAnESO,EAAAG,EAAA,aA6EF,SAASI,EAAaL,EAAc,CACvC,OAAOb,EAAS,CACZ,IAAK,eACD,aAAa,QAAQ,QAASa,CAAK,EACnC,MACJ,IAAK,iBACD,eAAe,QAAQ,QAASA,CAAK,EACrC,KACR,CAEAC,EAAU,CACd,CAXgBH,EAAAO,EAAA,gBAaT,SAASC,EAAYC,EAA+C,CACvEpB,EAAUoB,CACd,CAFgBT,EAAAQ,EAAA,eAKT,SAASE,EAAYC,EAAqB,CAC7CrB,EAAgBqB,CACpB,CAFgBX,EAAAU,EAAA,eAIhB,OAAO,iBAAiB,mBAAoBP,CAAS", "names": ["storage", "default_theme", "attribute", "color_scheme", "aborter", "subscribers", "subscribers_length", "media_query", "subscribe_to_theme_changes", "subscriber", "id", "__name", "update", "theme", "set_theme", "html", "class_list", "stored_theme", "change_theme", "set_storage", "setStorage", "set_default", "defaultTheme"] }