@vxrn/color-scheme 1.2.28 → 1.2.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/cjs/index.cjs +34 -58
  2. package/dist/cjs/index.js +27 -56
  3. package/dist/cjs/index.js.map +2 -2
  4. package/dist/cjs/index.native.js +23 -52
  5. package/dist/cjs/index.native.js.map +1 -1
  6. package/dist/cjs/systemScheme.cjs +40 -0
  7. package/dist/cjs/systemScheme.js +34 -0
  8. package/dist/cjs/systemScheme.js.map +6 -0
  9. package/dist/cjs/systemScheme.native.js +48 -0
  10. package/dist/cjs/systemScheme.native.js.map +1 -0
  11. package/dist/cjs/userScheme.cjs +95 -0
  12. package/dist/cjs/userScheme.js +80 -0
  13. package/dist/cjs/userScheme.js.map +6 -0
  14. package/dist/cjs/userScheme.native.js +109 -0
  15. package/dist/cjs/userScheme.native.js.map +1 -0
  16. package/dist/esm/index.js +29 -62
  17. package/dist/esm/index.js.map +2 -2
  18. package/dist/esm/index.mjs +28 -52
  19. package/dist/esm/index.mjs.map +1 -1
  20. package/dist/esm/index.native.js +18 -47
  21. package/dist/esm/index.native.js.map +1 -1
  22. package/dist/esm/systemScheme.js +19 -0
  23. package/dist/esm/systemScheme.js.map +6 -0
  24. package/dist/esm/systemScheme.mjs +16 -0
  25. package/dist/esm/systemScheme.mjs.map +1 -0
  26. package/dist/esm/systemScheme.native.js +21 -0
  27. package/dist/esm/systemScheme.native.js.map +1 -0
  28. package/dist/esm/userScheme.js +67 -0
  29. package/dist/esm/userScheme.js.map +6 -0
  30. package/dist/esm/userScheme.mjs +68 -0
  31. package/dist/esm/userScheme.mjs.map +1 -0
  32. package/dist/esm/userScheme.native.js +80 -0
  33. package/dist/esm/userScheme.native.js.map +1 -0
  34. package/package.json +3 -4
  35. package/src/index.tsx +28 -85
  36. package/src/systemScheme.native.ts +21 -0
  37. package/src/systemScheme.ts +26 -0
  38. package/src/userScheme.ts +149 -0
  39. package/types/index.d.ts +9 -15
  40. package/types/index.d.ts.map +1 -1
  41. package/types/systemScheme.d.ts +4 -0
  42. package/types/systemScheme.d.ts.map +1 -0
  43. package/types/systemScheme.native.d.ts +4 -0
  44. package/types/systemScheme.native.d.ts.map +1 -0
  45. package/types/userScheme.d.ts +20 -0
  46. package/types/userScheme.d.ts.map +1 -0
@@ -0,0 +1,16 @@
1
+ import { useIsomorphicLayoutEffect } from "@vxrn/use-isomorphic-layout-effect";
2
+ import { useState } from "react";
3
+ const media = typeof window < "u" && window.matchMedia ? window.matchMedia("(prefers-color-scheme: dark)") : null;
4
+ function getSystemScheme() {
5
+ return media?.matches ? "dark" : "light";
6
+ }
7
+ function useSystemScheme() {
8
+ const [scheme, setScheme] = useState("light");
9
+ return useIsomorphicLayoutEffect(() => {
10
+ setScheme(getSystemScheme());
11
+ const onChange = () => setScheme(getSystemScheme());
12
+ return media?.addEventListener("change", onChange), () => media?.removeEventListener("change", onChange);
13
+ }, []), scheme;
14
+ }
15
+ export { getSystemScheme, useSystemScheme };
16
+ //# sourceMappingURL=systemScheme.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useIsomorphicLayoutEffect","useState","media","window","matchMedia","getSystemScheme","matches","useSystemScheme","scheme","setScheme","onChange","addEventListener","removeEventListener"],"sources":["../../src/systemScheme.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,yBAAA,QAAiC;AAC1C,SAASC,QAAA,QAAgB;AAIzB,MAAMC,KAAA,GACJ,OAAOC,MAAA,GAAW,OAAeA,MAAA,CAAOC,UAAA,GACpCD,MAAA,CAAOC,UAAA,CAAW,8BAA8B,IAChD;AAEC,SAASC,gBAAA,EAA0B;EACxC,OAAOH,KAAA,EAAOI,OAAA,GAAU,SAAS;AACnC;AAEO,SAASC,gBAAA,EAA0B;EACxC,MAAM,CAACC,MAAA,EAAQC,SAAS,IAAIR,QAAA,CAAiB,OAAO;EAEpD,OAAAD,yBAAA,CAA0B,MAAM;IAC9BS,SAAA,CAAUJ,eAAA,CAAgB,CAAC;IAC3B,MAAMK,QAAA,GAAWA,CAAA,KAAMD,SAAA,CAAUJ,eAAA,CAAgB,CAAC;IAClD,OAAAH,KAAA,EAAOS,gBAAA,CAAiB,UAAUD,QAAQ,GACnC,MAAMR,KAAA,EAAOU,mBAAA,CAAoB,UAAUF,QAAQ;EAC5D,GAAG,EAAE,GAEEF,MAAA;AACT","ignoreList":[]}
@@ -0,0 +1,21 @@
1
+ import { useState, useEffect } from "react";
2
+ import { Appearance } from "react-native";
3
+ function getSystemScheme() {
4
+ return Appearance.getColorScheme() || "light";
5
+ }
6
+ function useSystemScheme() {
7
+ var [scheme, setScheme] = useState(getSystemScheme);
8
+ return useEffect(function () {
9
+ var subscription = Appearance.addChangeListener(function (param) {
10
+ var {
11
+ colorScheme
12
+ } = param;
13
+ setScheme(colorScheme || "light");
14
+ });
15
+ return function () {
16
+ return subscription.remove();
17
+ };
18
+ }, []), scheme;
19
+ }
20
+ export { getSystemScheme, useSystemScheme };
21
+ //# sourceMappingURL=systemScheme.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useState","useEffect","Appearance","getSystemScheme","getColorScheme","useSystemScheme","scheme","setScheme","subscription","addChangeListener","param","colorScheme","remove"],"sources":["../../src/systemScheme.native.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,EAAUC,SAAA,QAAiB;AACpC,SAASC,UAAA,QAAkB;AACpB,SAASC,gBAAA,EAAkB;EAC9B,OAAOD,UAAA,CAAWE,cAAA,CAAe,KAAK;AAC1C;AACO,SAASC,gBAAA,EAAkB;EAC9B,IAAI,CAACC,MAAA,EAAQC,SAAS,IAAIP,QAAA,CAASG,eAAe;EAClD,OAAAF,SAAA,CAAU,YAAW;IACjB,IAAIO,YAAA,GAAeN,UAAA,CAAWO,iBAAA,CAAkB,UAASC,KAAA,EAAO;MAC5D,IAAI;QAAEC;MAAY,IAAID,KAAA;MACtBH,SAAA,CAAUI,WAAA,IAAe,OAAO;IACpC,CAAC;IACD,OAAO,YAAW;MACd,OAAOH,YAAA,CAAaI,MAAA,CAAO;IAC/B;EACJ,GAAG,EAAE,GACEN,MAAA;AACX","ignoreList":[]}
@@ -0,0 +1,67 @@
1
+ import { useIsomorphicLayoutEffect } from "@vxrn/use-isomorphic-layout-effect";
2
+ import { useState, useMemo } from "react";
3
+
4
+ import { getSystemScheme } from "./systemScheme";
5
+ const listeners = /* @__PURE__ */ new Set(), storageKey = "vxrn-scheme";
6
+ let currentSetting = "system", currentValue = "light", isWebListening = !1;
7
+ function startWebListener() {
8
+ if (isWebListening) return;
9
+ isWebListening = !0;
10
+ const matcher = typeof window < "u" ? window.matchMedia?.("(prefers-color-scheme: dark)") : null, onSystemChange = () => {
11
+ currentSetting === "system" && updateValueFromSystem();
12
+ };
13
+ onSystemChange(), matcher?.addEventListener?.("change", onSystemChange);
14
+ }
15
+ function resolveValue(setting) {
16
+ return setting === "system" ? getSystemScheme() : setting;
17
+ }
18
+ function updateValueFromSystem() {
19
+ const value = resolveValue("system");
20
+ value !== currentValue && (currentValue = value, listeners.forEach((l) => {
21
+ l(currentSetting, currentValue);
22
+ }));
23
+ }
24
+ function updateScheme(setting) {
25
+ const value = setting === "system" ? resolveValue("system") : setting;
26
+ (value !== currentValue || currentSetting !== setting) && (currentSetting = setting, currentValue = value, listeners.forEach((l) => {
27
+ l(currentSetting, currentValue);
28
+ }));
29
+ }
30
+ function setUserScheme(setting) {
31
+ typeof localStorage < "u" && localStorage.setItem(storageKey, setting), updateScheme(setting);
32
+ }
33
+ function getUserScheme() {
34
+ return { setting: currentSetting, value: currentValue };
35
+ }
36
+ function onUserSchemeChange(listener) {
37
+ return listeners.add(listener), listener(currentSetting, currentValue), () => {
38
+ listeners.delete(listener);
39
+ };
40
+ }
41
+ function useUserScheme() {
42
+ const [state, setState] = useState(() => getUserScheme());
43
+ return useIsomorphicLayoutEffect(() => {
44
+ if (typeof localStorage < "u") {
45
+ const stored = localStorage.getItem(storageKey);
46
+ stored && updateScheme(stored);
47
+ }
48
+ const dispose = onUserSchemeChange((setting, value) => {
49
+ setState({ setting, value });
50
+ });
51
+ return startWebListener(), dispose;
52
+ }, []), useMemo(
53
+ () => ({
54
+ setting: state.setting,
55
+ value: state.value,
56
+ set: setUserScheme
57
+ }),
58
+ [state.setting, state.value]
59
+ );
60
+ }
61
+ export {
62
+ getUserScheme,
63
+ onUserSchemeChange,
64
+ setUserScheme,
65
+ useUserScheme
66
+ };
67
+ //# sourceMappingURL=userScheme.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/userScheme.ts"],
4
+ "mappings": "AAAA,SAAS,iCAAiC;AAC1C,SAAS,UAAU,eAAe;AAClC,OAA2B;AAC3B,SAAS,uBAAoC;AAe7C,MAAM,YAAY,oBAAI,IAAoB,GACpC,aAAa;AAEnB,IAAI,iBAAgC,UAChC,eAAuB,SAiBvB,iBAAiB;AACrB,SAAS,mBAAmB;AAC1B,MAAI,eAAgB;AACpB,mBAAiB;AAEjB,QAAM,UACJ,OAAO,SAAW,MAAc,OAAO,aAAa,8BAA8B,IAAI,MAElF,iBAAiB,MAAM;AAC3B,IAAI,mBAAmB,YACrB,sBAAsB;AAAA,EAE1B;AAEA,iBAAe,GACf,SAAS,mBAAmB,UAAU,cAAc;AACtD;AAEA,SAAS,aAAa,SAAgC;AACpD,SAAI,YAAY,WAIP,gBAAgB,IAElB;AACT;AAGA,SAAS,wBAAwB;AAC/B,QAAM,QAAQ,aAAa,QAAQ;AACnC,EAAI,UAAU,iBACZ,eAAe,OAMf,UAAU,QAAQ,CAAC,MAAM;AACvB,MAAE,gBAAgB,YAAY;AAAA,EAChC,CAAC;AAEL;AAEA,SAAS,aAAa,SAAwB;AAC5C,QAAM,QAAQ,YAAY,WAAW,aAAa,QAAQ,IAAI;AAE9D,GAAI,UAAU,gBAAgB,mBAAmB,aAC/C,iBAAiB,SACjB,eAAe,OAMf,UAAU,QAAQ,CAAC,MAAM;AACvB,MAAE,gBAAgB,YAAY;AAAA,EAChC,CAAC;AAEL;AAEO,SAAS,cAAc,SAAwB;AACpD,EAAI,OAAO,eAAiB,OAC1B,aAAa,QAAQ,YAAY,OAAO,GAE1C,aAAa,OAAO;AACtB;AAEO,SAAS,gBAA2D;AACzE,SAAO,EAAE,SAAS,gBAAgB,OAAO,aAAa;AACxD;AAEO,SAAS,mBAAmB,UAA0B;AAC3D,mBAAU,IAAI,QAAQ,GACtB,SAAS,gBAAgB,YAAY,GAC9B,MAAM;AACX,cAAU,OAAO,QAAQ;AAAA,EAC3B;AACF;AAEO,SAAS,gBAA4B;AAC1C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,MAAM,cAAc,CAAC;AAExD,mCAA0B,MAAM;AAE9B,QAAI,OAAO,eAAiB,KAAa;AACvC,YAAM,SAAS,aAAa,QAAQ,UAAU;AAC9C,MAAI,UACF,aAAa,MAAM;AAAA,IAEvB;AAEA,UAAM,UAAU,mBAAmB,CAAC,SAAS,UAAU;AACrD,eAAS,EAAE,SAAS,MAAM,CAAC;AAAA,IAC7B,CAAC;AAED,4BAAiB,GAEV;AAAA,EACT,GAAG,CAAC,CAAC,GAEE;AAAA,IACL,OAAO;AAAA,MACL,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,MACb,KAAK;AAAA,IACP;AAAA,IACA,CAAC,MAAM,SAAS,MAAM,KAAK;AAAA,EAC7B;AACF;",
5
+ "names": []
6
+ }
@@ -0,0 +1,68 @@
1
+ import { useIsomorphicLayoutEffect } from "@vxrn/use-isomorphic-layout-effect";
2
+ import { useState, useMemo } from "react";
3
+ import { getSystemScheme } from "./systemScheme.mjs";
4
+ const listeners = /* @__PURE__ */new Set(),
5
+ storageKey = "vxrn-scheme";
6
+ let currentSetting = "system",
7
+ currentValue = "light",
8
+ isWebListening = !1;
9
+ function startWebListener() {
10
+ if (isWebListening) return;
11
+ isWebListening = !0;
12
+ const matcher = typeof window < "u" ? window.matchMedia?.("(prefers-color-scheme: dark)") : null,
13
+ onSystemChange = () => {
14
+ currentSetting === "system" && updateValueFromSystem();
15
+ };
16
+ onSystemChange(), matcher?.addEventListener?.("change", onSystemChange);
17
+ }
18
+ function resolveValue(setting) {
19
+ return setting === "system" ? getSystemScheme() : setting;
20
+ }
21
+ function updateValueFromSystem() {
22
+ const value = resolveValue("system");
23
+ value !== currentValue && (currentValue = value, listeners.forEach(l => {
24
+ l(currentSetting, currentValue);
25
+ }));
26
+ }
27
+ function updateScheme(setting) {
28
+ const value = setting === "system" ? resolveValue("system") : setting;
29
+ (value !== currentValue || currentSetting !== setting) && (currentSetting = setting, currentValue = value, listeners.forEach(l => {
30
+ l(currentSetting, currentValue);
31
+ }));
32
+ }
33
+ function setUserScheme(setting) {
34
+ typeof localStorage < "u" && localStorage.setItem(storageKey, setting), updateScheme(setting);
35
+ }
36
+ function getUserScheme() {
37
+ return {
38
+ setting: currentSetting,
39
+ value: currentValue
40
+ };
41
+ }
42
+ function onUserSchemeChange(listener) {
43
+ return listeners.add(listener), listener(currentSetting, currentValue), () => {
44
+ listeners.delete(listener);
45
+ };
46
+ }
47
+ function useUserScheme() {
48
+ const [state, setState] = useState(() => getUserScheme());
49
+ return useIsomorphicLayoutEffect(() => {
50
+ if (typeof localStorage < "u") {
51
+ const stored = localStorage.getItem(storageKey);
52
+ stored && updateScheme(stored);
53
+ }
54
+ const dispose = onUserSchemeChange((setting, value) => {
55
+ setState({
56
+ setting,
57
+ value
58
+ });
59
+ });
60
+ return startWebListener(), dispose;
61
+ }, []), useMemo(() => ({
62
+ setting: state.setting,
63
+ value: state.value,
64
+ set: setUserScheme
65
+ }), [state.setting, state.value]);
66
+ }
67
+ export { getUserScheme, onUserSchemeChange, setUserScheme, useUserScheme };
68
+ //# sourceMappingURL=userScheme.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useIsomorphicLayoutEffect","useState","useMemo","getSystemScheme","listeners","Set","storageKey","currentSetting","currentValue","isWebListening","startWebListener","matcher","window","matchMedia","onSystemChange","updateValueFromSystem","addEventListener","resolveValue","setting","value","forEach","l","updateScheme","setUserScheme","localStorage","setItem","getUserScheme","onUserSchemeChange","listener","add","delete","useUserScheme","state","setState","stored","getItem","dispose","set"],"sources":["../../src/userScheme.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,yBAAA,QAAiC;AAC1C,SAASC,QAAA,EAAUC,OAAA,QAAe;AAElC,SAASC,eAAA,QAAoC;AAe7C,MAAMC,SAAA,GAAY,mBAAIC,GAAA,CAAoB;EACpCC,UAAA,GAAa;AAEnB,IAAIC,cAAA,GAAgC;EAChCC,YAAA,GAAuB;EAiBvBC,cAAA,GAAiB;AACrB,SAASC,iBAAA,EAAmB;EAC1B,IAAID,cAAA,EAAgB;EACpBA,cAAA,GAAiB;EAEjB,MAAME,OAAA,GACJ,OAAOC,MAAA,GAAW,MAAcA,MAAA,CAAOC,UAAA,GAAa,8BAA8B,IAAI;IAElFC,cAAA,GAAiBA,CAAA,KAAM;MACvBP,cAAA,KAAmB,YACrBQ,qBAAA,CAAsB;IAE1B;EAEAD,cAAA,CAAe,GACfH,OAAA,EAASK,gBAAA,GAAmB,UAAUF,cAAc;AACtD;AAEA,SAASG,aAAaC,OAAA,EAAgC;EACpD,OAAIA,OAAA,KAAY,WAIPf,eAAA,CAAgB,IAElBe,OAAA;AACT;AAGA,SAASH,sBAAA,EAAwB;EAC/B,MAAMI,KAAA,GAAQF,YAAA,CAAa,QAAQ;EAC/BE,KAAA,KAAUX,YAAA,KACZA,YAAA,GAAeW,KAAA,EAMff,SAAA,CAAUgB,OAAA,CAASC,CAAA,IAAM;IACvBA,CAAA,CAAEd,cAAA,EAAgBC,YAAY;EAChC,CAAC;AAEL;AAEA,SAASc,aAAaJ,OAAA,EAAwB;EAC5C,MAAMC,KAAA,GAAQD,OAAA,KAAY,WAAWD,YAAA,CAAa,QAAQ,IAAIC,OAAA;EAE9D,CAAIC,KAAA,KAAUX,YAAA,IAAgBD,cAAA,KAAmBW,OAAA,MAC/CX,cAAA,GAAiBW,OAAA,EACjBV,YAAA,GAAeW,KAAA,EAMff,SAAA,CAAUgB,OAAA,CAASC,CAAA,IAAM;IACvBA,CAAA,CAAEd,cAAA,EAAgBC,YAAY;EAChC,CAAC;AAEL;AAEO,SAASe,cAAcL,OAAA,EAAwB;EAChD,OAAOM,YAAA,GAAiB,OAC1BA,YAAA,CAAaC,OAAA,CAAQnB,UAAA,EAAYY,OAAO,GAE1CI,YAAA,CAAaJ,OAAO;AACtB;AAEO,SAASQ,cAAA,EAA2D;EACzE,OAAO;IAAER,OAAA,EAASX,cAAA;IAAgBY,KAAA,EAAOX;EAAa;AACxD;AAEO,SAASmB,mBAAmBC,QAAA,EAA0B;EAC3D,OAAAxB,SAAA,CAAUyB,GAAA,CAAID,QAAQ,GACtBA,QAAA,CAASrB,cAAA,EAAgBC,YAAY,GAC9B,MAAM;IACXJ,SAAA,CAAU0B,MAAA,CAAOF,QAAQ;EAC3B;AACF;AAEO,SAASG,cAAA,EAA4B;EAC1C,MAAM,CAACC,KAAA,EAAOC,QAAQ,IAAIhC,QAAA,CAAS,MAAMyB,aAAA,CAAc,CAAC;EAExD,OAAA1B,yBAAA,CAA0B,MAAM;IAE9B,IAAI,OAAOwB,YAAA,GAAiB,KAAa;MACvC,MAAMU,MAAA,GAASV,YAAA,CAAaW,OAAA,CAAQ7B,UAAU;MAC1C4B,MAAA,IACFZ,YAAA,CAAaY,MAAM;IAEvB;IAEA,MAAME,OAAA,GAAUT,kBAAA,CAAmB,CAACT,OAAA,EAASC,KAAA,KAAU;MACrDc,QAAA,CAAS;QAAEf,OAAA;QAASC;MAAM,CAAC;IAC7B,CAAC;IAED,OAAAT,gBAAA,CAAiB,GAEV0B,OAAA;EACT,GAAG,EAAE,GAEElC,OAAA,CACL,OAAO;IACLgB,OAAA,EAASc,KAAA,CAAMd,OAAA;IACfC,KAAA,EAAOa,KAAA,CAAMb,KAAA;IACbkB,GAAA,EAAKd;EACP,IACA,CAACS,KAAA,CAAMd,OAAA,EAASc,KAAA,CAAMb,KAAK,CAC7B;AACF","ignoreList":[]}
@@ -0,0 +1,80 @@
1
+ import { useIsomorphicLayoutEffect } from "@vxrn/use-isomorphic-layout-effect";
2
+ import { useState, useMemo } from "react";
3
+ import { Appearance } from "react-native";
4
+ import { getSystemScheme } from "./systemScheme.native.js";
5
+ var listeners = /* @__PURE__ */new Set(),
6
+ storageKey = "vxrn-scheme",
7
+ currentSetting = "system",
8
+ currentValue = "light";
9
+ Appearance.addChangeListener(function (next) {
10
+ currentSetting === "system" && next.colorScheme && updateValueFromSystem();
11
+ });
12
+ var cur = Appearance.getColorScheme();
13
+ cur && currentSetting === "system" && (currentValue = cur);
14
+ var isWebListening = !1;
15
+ function startWebListener() {
16
+ var _window_matchMedia, _window, _matcher_addEventListener;
17
+ if (!isWebListening) {
18
+ isWebListening = !0;
19
+ var matcher = typeof window < "u" ? (_window_matchMedia = (_window = window).matchMedia) === null || _window_matchMedia === void 0 ? void 0 : _window_matchMedia.call(_window, "(prefers-color-scheme: dark)") : null,
20
+ onSystemChange = function () {
21
+ currentSetting === "system" && updateValueFromSystem();
22
+ };
23
+ onSystemChange(), matcher == null || (_matcher_addEventListener = matcher.addEventListener) === null || _matcher_addEventListener === void 0 || _matcher_addEventListener.call(matcher, "change", onSystemChange);
24
+ }
25
+ }
26
+ function resolveValue(setting) {
27
+ return setting === "system" ? Appearance.getColorScheme() || "light" : setting;
28
+ }
29
+ function updateValueFromSystem() {
30
+ var value = resolveValue("system");
31
+ value !== currentValue && (currentValue = value, Appearance.setColorScheme(value), listeners.forEach(function (l) {
32
+ l(currentSetting, currentValue);
33
+ }));
34
+ }
35
+ function updateScheme(setting) {
36
+ var value = setting === "system" ? resolveValue("system") : setting;
37
+ (value !== currentValue || currentSetting !== setting) && (currentSetting = setting, currentValue = value, Appearance.setColorScheme(value), listeners.forEach(function (l) {
38
+ l(currentSetting, currentValue);
39
+ }));
40
+ }
41
+ function setUserScheme(setting) {
42
+ typeof localStorage < "u" && localStorage.setItem(storageKey, setting), updateScheme(setting);
43
+ }
44
+ function getUserScheme() {
45
+ return {
46
+ setting: currentSetting,
47
+ value: currentValue
48
+ };
49
+ }
50
+ function onUserSchemeChange(listener) {
51
+ return listeners.add(listener), listener(currentSetting, currentValue), function () {
52
+ listeners.delete(listener);
53
+ };
54
+ }
55
+ function useUserScheme() {
56
+ var [state, setState] = useState(function () {
57
+ return getUserScheme();
58
+ });
59
+ return useIsomorphicLayoutEffect(function () {
60
+ if (typeof localStorage < "u") {
61
+ var stored = localStorage.getItem(storageKey);
62
+ stored && updateScheme(stored);
63
+ }
64
+ var dispose = onUserSchemeChange(function (setting, value) {
65
+ setState({
66
+ setting,
67
+ value
68
+ });
69
+ });
70
+ return startWebListener(), dispose;
71
+ }, []), useMemo(function () {
72
+ return {
73
+ setting: state.setting,
74
+ value: state.value,
75
+ set: setUserScheme
76
+ };
77
+ }, [state.setting, state.value]);
78
+ }
79
+ export { getUserScheme, onUserSchemeChange, setUserScheme, useUserScheme };
80
+ //# sourceMappingURL=userScheme.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useIsomorphicLayoutEffect","useState","useMemo","Appearance","getSystemScheme","listeners","Set","storageKey","currentSetting","currentValue","addChangeListener","next","colorScheme","updateValueFromSystem","cur","getColorScheme","isWebListening","startWebListener","_window_matchMedia","_window","_matcher_addEventListener","matcher","window","matchMedia","call","onSystemChange","addEventListener","resolveValue","setting","value","setColorScheme","forEach","l","updateScheme","setUserScheme","localStorage","setItem","getUserScheme","onUserSchemeChange","listener","add","delete","useUserScheme","state","setState","stored","getItem","dispose"],"sources":["../../src/userScheme.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vxrn/color-scheme",
3
- "version": "1.2.28",
3
+ "version": "1.2.31",
4
4
  "sideEffects": false,
5
5
  "exports": {
6
6
  "./package.json": "./package.json",
@@ -32,11 +32,10 @@
32
32
  "watch": "tamagui-build --watch"
33
33
  },
34
34
  "dependencies": {
35
- "@vxrn/universal-color-scheme": "1.2.28",
36
- "@vxrn/use-isomorphic-layout-effect": "1.2.28"
35
+ "@vxrn/use-isomorphic-layout-effect": "1.2.31"
37
36
  },
38
37
  "devDependencies": {
39
- "@tamagui/build": "^1.139.2",
38
+ "@tamagui/build": "^1.140.2",
40
39
  "react": "19.1.0",
41
40
  "react-native": "0.81.5"
42
41
  },
package/src/index.tsx CHANGED
@@ -1,76 +1,36 @@
1
- import {
2
- type ColorSchemeName,
3
- setColorScheme,
4
- useColorScheme as useColorSchemeBase,
5
- useColorSchemeSetting,
6
- } from '@vxrn/universal-color-scheme'
7
1
  import { useIsomorphicLayoutEffect } from '@vxrn/use-isomorphic-layout-effect'
8
- import { createContext, useContext, useMemo } from 'react'
2
+ import type { Scheme } from './systemScheme'
3
+ import { useUserScheme } from './userScheme'
9
4
 
10
- export type Scheme = 'light' | 'dark'
11
- export type SchemeSetting = 'system' | 'light' | 'dark'
5
+ // re-export types
6
+ export type { Scheme } from './systemScheme'
7
+ export type { SchemeSetting, UserScheme } from './userScheme'
12
8
 
13
- export { getColorScheme, onColorSchemeChange } from '@vxrn/universal-color-scheme'
9
+ // re-export core
10
+ export { getSystemScheme, useSystemScheme } from './systemScheme'
11
+ export { getUserScheme, onUserSchemeChange, setUserScheme, useUserScheme } from './userScheme'
14
12
 
15
13
  const storageKey = 'vxrn-scheme'
16
14
 
17
- export const clearColorSchemeSetting = () => {
18
- setSchemeSetting('system')
19
- }
20
-
21
- const getSetting = (): SchemeSetting =>
22
- (typeof localStorage !== 'undefined' && (localStorage.getItem(storageKey) as SchemeSetting)) ||
23
- 'system'
24
-
25
- const SchemeContext = createContext<{
26
- setting: SchemeSetting
27
- scheme: 'light' | 'dark'
28
- }>({
29
- setting: 'system',
30
- scheme: 'light',
31
- })
32
-
33
- export const useColorScheme = () => {
34
- const [state] = useColorSchemeBase()
35
- return [state, setSchemeSetting] as const
36
- }
37
-
38
- export function useSchemeSetting() {
39
- const values = useContext(SchemeContext)
40
- return [values, setSchemeSetting] as const
41
- }
42
-
43
- export function setSchemeSetting(next: SchemeSetting) {
44
- if (typeof localStorage !== 'undefined') {
45
- localStorage.setItem(storageKey, next)
46
- }
47
- setColorScheme(next)
48
- }
49
-
50
15
  export function SchemeProvider({
51
16
  children,
52
- // defaults to tamagui-compatible
53
17
  getClassName = (name) => `t_${name}`,
54
18
  }: {
55
19
  children: any
56
- getClassName?: (name: ColorSchemeName) => string
20
+ getClassName?: (name: Scheme) => string
57
21
  }) {
58
- const [colorSchemeSetting] = useColorSchemeSetting()
59
- const [colorScheme] = useColorScheme()
22
+ const { value } = useUserScheme()
60
23
 
61
24
  if (process.env.TAMAGUI_TARGET !== 'native') {
62
25
  useIsomorphicLayoutEffect(() => {
63
- // on startup lets set from localstorage
64
- setColorScheme(getSetting())
65
-
66
- const toAdd = getClassName(colorScheme)
26
+ const toAdd = getClassName(value)
67
27
  const { classList } = document.documentElement
68
28
  if (!classList.contains(toAdd)) {
69
- const toRemove = colorScheme === 'light' ? 'dark' : 'light'
29
+ const toRemove = value === 'light' ? 'dark' : 'light'
70
30
  classList.remove(getClassName(toRemove))
71
31
  classList.add(toAdd)
72
32
  }
73
- }, [colorScheme])
33
+ }, [value])
74
34
  }
75
35
 
76
36
  return (
@@ -79,59 +39,42 @@ export function SchemeProvider({
79
39
  <script
80
40
  dangerouslySetInnerHTML={{
81
41
  __html: `let d = document.documentElement.classList
82
- d.remove('${getClassName('light')}')
83
- d.remove('${getClassName('dark')}')
84
- let e = localStorage.getItem('${storageKey}')
85
- let t =
86
- 'system' === e || !e
87
- ? window.matchMedia('(prefers-color-scheme: dark)').matches
88
- : e === 'dark'
89
- t ? d.add('${getClassName('dark')}') : d.add('${getClassName('light')}')
90
- `,
42
+ d.remove('${getClassName('light')}')
43
+ d.remove('${getClassName('dark')}')
44
+ let e = localStorage.getItem('${storageKey}')
45
+ let t = 'system' === e || !e
46
+ ? window.matchMedia('(prefers-color-scheme: dark)').matches
47
+ : e === 'dark'
48
+ t ? d.add('${getClassName('dark')}') : d.add('${getClassName('light')}')
49
+ `,
91
50
  }}
92
51
  />
93
52
  )}
94
- <SchemeContext.Provider
95
- value={useMemo(
96
- () => ({
97
- scheme: colorScheme,
98
- setting: colorSchemeSetting,
99
- }),
100
- [colorScheme, colorSchemeSetting]
101
- )}
102
- >
103
- {children}
104
- </SchemeContext.Provider>
53
+ {children}
105
54
  </>
106
55
  )
107
56
  }
108
57
 
109
- export const MetaTheme = ({
58
+ export function MetaTheme({
110
59
  color,
111
60
  darkColor,
112
61
  lightColor,
113
62
  }: {
114
- color: string
63
+ color?: string
115
64
  darkColor: string
116
65
  lightColor: string
117
- }) => {
118
- const [colorScheme] = useColorScheme()
66
+ }) {
67
+ const { value } = useUserScheme()
119
68
 
120
69
  return (
121
70
  <>
122
- {/* itemProp removes hoisting - react wasnt de-duping it properly causing two in DOM */}
123
- {/* maybe bug in safari or react */}
124
71
  <meta
125
72
  itemProp="__deopt"
126
- // because the script below runs before render it actually ruins our nice ssr logic here
127
- // instead we just avoid the warning its a single tag
128
73
  suppressHydrationWarning
129
74
  id="vxrn-theme-color"
130
75
  name="theme-color"
131
- content={color ?? (colorScheme === 'dark' ? darkColor : lightColor)}
76
+ content={color ?? (value === 'dark' ? darkColor : lightColor)}
132
77
  />
133
-
134
- {/* ssr compat theme-color */}
135
78
  <script
136
79
  id="meta-theme-hydrate"
137
80
  dangerouslySetInnerHTML={{
@@ -140,7 +83,7 @@ let dc = document.getElementById('vxrn-theme-color')
140
83
  let e1 = localStorage.getItem('${storageKey}')
141
84
  let isD = 'system' === e1 || !e1 ? window.matchMedia('(prefers-color-scheme: dark)').matches : e1 === 'dark'
142
85
  dc.setAttribute('content', isD ? '${darkColor}' : '${lightColor}')
143
- `,
86
+ `,
144
87
  }}
145
88
  />
146
89
  </>
@@ -0,0 +1,21 @@
1
+ import { useState, useEffect } from 'react'
2
+ import { Appearance } from 'react-native'
3
+
4
+ export type Scheme = 'light' | 'dark'
5
+
6
+ export function getSystemScheme(): Scheme {
7
+ return Appearance.getColorScheme() || 'light'
8
+ }
9
+
10
+ export function useSystemScheme(): Scheme {
11
+ const [scheme, setScheme] = useState<Scheme>(getSystemScheme)
12
+
13
+ useEffect(() => {
14
+ const subscription = Appearance.addChangeListener(({ colorScheme }) => {
15
+ setScheme(colorScheme || 'light')
16
+ })
17
+ return () => subscription.remove()
18
+ }, [])
19
+
20
+ return scheme
21
+ }
@@ -0,0 +1,26 @@
1
+ import { useIsomorphicLayoutEffect } from '@vxrn/use-isomorphic-layout-effect'
2
+ import { useState } from 'react'
3
+
4
+ export type Scheme = 'light' | 'dark'
5
+
6
+ const media =
7
+ typeof window !== 'undefined' && window.matchMedia
8
+ ? window.matchMedia('(prefers-color-scheme: dark)')
9
+ : null
10
+
11
+ export function getSystemScheme(): Scheme {
12
+ return media?.matches ? 'dark' : 'light'
13
+ }
14
+
15
+ export function useSystemScheme(): Scheme {
16
+ const [scheme, setScheme] = useState<Scheme>('light')
17
+
18
+ useIsomorphicLayoutEffect(() => {
19
+ setScheme(getSystemScheme())
20
+ const onChange = () => setScheme(getSystemScheme())
21
+ media?.addEventListener('change', onChange)
22
+ return () => media?.removeEventListener('change', onChange)
23
+ }, [])
24
+
25
+ return scheme
26
+ }