@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.
- package/dist/cjs/index.cjs +34 -58
- package/dist/cjs/index.js +27 -56
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/index.native.js +23 -52
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/systemScheme.cjs +40 -0
- package/dist/cjs/systemScheme.js +34 -0
- package/dist/cjs/systemScheme.js.map +6 -0
- package/dist/cjs/systemScheme.native.js +48 -0
- package/dist/cjs/systemScheme.native.js.map +1 -0
- package/dist/cjs/userScheme.cjs +95 -0
- package/dist/cjs/userScheme.js +80 -0
- package/dist/cjs/userScheme.js.map +6 -0
- package/dist/cjs/userScheme.native.js +109 -0
- package/dist/cjs/userScheme.native.js.map +1 -0
- package/dist/esm/index.js +29 -62
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/index.mjs +28 -52
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +18 -47
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/systemScheme.js +19 -0
- package/dist/esm/systemScheme.js.map +6 -0
- package/dist/esm/systemScheme.mjs +16 -0
- package/dist/esm/systemScheme.mjs.map +1 -0
- package/dist/esm/systemScheme.native.js +21 -0
- package/dist/esm/systemScheme.native.js.map +1 -0
- package/dist/esm/userScheme.js +67 -0
- package/dist/esm/userScheme.js.map +6 -0
- package/dist/esm/userScheme.mjs +68 -0
- package/dist/esm/userScheme.mjs.map +1 -0
- package/dist/esm/userScheme.native.js +80 -0
- package/dist/esm/userScheme.native.js.map +1 -0
- package/package.json +3 -4
- package/src/index.tsx +28 -85
- package/src/systemScheme.native.ts +21 -0
- package/src/systemScheme.ts +26 -0
- package/src/userScheme.ts +149 -0
- package/types/index.d.ts +9 -15
- package/types/index.d.ts.map +1 -1
- package/types/systemScheme.d.ts +4 -0
- package/types/systemScheme.d.ts.map +1 -0
- package/types/systemScheme.native.d.ts +4 -0
- package/types/systemScheme.native.d.ts.map +1 -0
- package/types/userScheme.d.ts +20 -0
- package/types/userScheme.d.ts.map +1 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { useIsomorphicLayoutEffect } from '@vxrn/use-isomorphic-layout-effect'
|
|
2
|
+
import { useState, useMemo } from 'react'
|
|
3
|
+
import { Appearance } from 'react-native'
|
|
4
|
+
import { getSystemScheme, type Scheme } from './systemScheme'
|
|
5
|
+
|
|
6
|
+
export type SchemeSetting = 'system' | 'light' | 'dark'
|
|
7
|
+
|
|
8
|
+
export type UserScheme = {
|
|
9
|
+
/** The user's preference: 'system', 'light', or 'dark' */
|
|
10
|
+
setting: SchemeSetting
|
|
11
|
+
/** The resolved scheme: 'light' or 'dark' */
|
|
12
|
+
value: Scheme
|
|
13
|
+
/** Update the scheme setting */
|
|
14
|
+
set: (setting: SchemeSetting) => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type SchemeListener = (setting: SchemeSetting, value: Scheme) => void
|
|
18
|
+
|
|
19
|
+
const listeners = new Set<SchemeListener>()
|
|
20
|
+
const storageKey = 'vxrn-scheme'
|
|
21
|
+
|
|
22
|
+
let currentSetting: SchemeSetting = 'system'
|
|
23
|
+
let currentValue: Scheme = 'light'
|
|
24
|
+
|
|
25
|
+
// native: set up listener at module level
|
|
26
|
+
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
27
|
+
Appearance.addChangeListener((next) => {
|
|
28
|
+
if (currentSetting === 'system' && next.colorScheme) {
|
|
29
|
+
updateValueFromSystem()
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const cur = Appearance.getColorScheme()
|
|
34
|
+
if (cur && currentSetting === 'system') {
|
|
35
|
+
currentValue = cur
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// web: lazy listener setup for SSR safety
|
|
40
|
+
let isWebListening = false
|
|
41
|
+
function startWebListener() {
|
|
42
|
+
if (isWebListening) return
|
|
43
|
+
isWebListening = true
|
|
44
|
+
|
|
45
|
+
const matcher =
|
|
46
|
+
typeof window !== 'undefined' ? window.matchMedia?.('(prefers-color-scheme: dark)') : null
|
|
47
|
+
|
|
48
|
+
const onSystemChange = () => {
|
|
49
|
+
if (currentSetting === 'system') {
|
|
50
|
+
updateValueFromSystem()
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
onSystemChange()
|
|
55
|
+
matcher?.addEventListener?.('change', onSystemChange)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function resolveValue(setting: SchemeSetting): Scheme {
|
|
59
|
+
if (setting === 'system') {
|
|
60
|
+
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
61
|
+
return Appearance.getColorScheme() || 'light'
|
|
62
|
+
}
|
|
63
|
+
return getSystemScheme()
|
|
64
|
+
}
|
|
65
|
+
return setting
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Only update the resolved value when system theme changes (don't change setting)
|
|
69
|
+
function updateValueFromSystem() {
|
|
70
|
+
const value = resolveValue('system')
|
|
71
|
+
if (value !== currentValue) {
|
|
72
|
+
currentValue = value
|
|
73
|
+
|
|
74
|
+
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
75
|
+
Appearance.setColorScheme(value)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
listeners.forEach((l) => {
|
|
79
|
+
l(currentSetting, currentValue)
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function updateScheme(setting: SchemeSetting) {
|
|
85
|
+
const value = setting === 'system' ? resolveValue('system') : setting
|
|
86
|
+
|
|
87
|
+
if (value !== currentValue || currentSetting !== setting) {
|
|
88
|
+
currentSetting = setting
|
|
89
|
+
currentValue = value
|
|
90
|
+
|
|
91
|
+
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
92
|
+
Appearance.setColorScheme(value)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
listeners.forEach((l) => {
|
|
96
|
+
l(currentSetting, currentValue)
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function setUserScheme(setting: SchemeSetting) {
|
|
102
|
+
if (typeof localStorage !== 'undefined') {
|
|
103
|
+
localStorage.setItem(storageKey, setting)
|
|
104
|
+
}
|
|
105
|
+
updateScheme(setting)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function getUserScheme(): { setting: SchemeSetting; value: Scheme } {
|
|
109
|
+
return { setting: currentSetting, value: currentValue }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function onUserSchemeChange(listener: SchemeListener) {
|
|
113
|
+
listeners.add(listener)
|
|
114
|
+
listener(currentSetting, currentValue)
|
|
115
|
+
return () => {
|
|
116
|
+
listeners.delete(listener)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function useUserScheme(): UserScheme {
|
|
121
|
+
const [state, setState] = useState(() => getUserScheme())
|
|
122
|
+
|
|
123
|
+
useIsomorphicLayoutEffect(() => {
|
|
124
|
+
// restore from localStorage on mount
|
|
125
|
+
if (typeof localStorage !== 'undefined') {
|
|
126
|
+
const stored = localStorage.getItem(storageKey) as SchemeSetting | null
|
|
127
|
+
if (stored) {
|
|
128
|
+
updateScheme(stored)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const dispose = onUserSchemeChange((setting, value) => {
|
|
133
|
+
setState({ setting, value })
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
startWebListener()
|
|
137
|
+
|
|
138
|
+
return dispose
|
|
139
|
+
}, [])
|
|
140
|
+
|
|
141
|
+
return useMemo(
|
|
142
|
+
() => ({
|
|
143
|
+
setting: state.setting,
|
|
144
|
+
value: state.value,
|
|
145
|
+
set: setUserScheme,
|
|
146
|
+
}),
|
|
147
|
+
[state.setting, state.value]
|
|
148
|
+
)
|
|
149
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type Scheme
|
|
3
|
-
export type SchemeSetting
|
|
4
|
-
export {
|
|
5
|
-
export
|
|
6
|
-
export declare const useColorScheme: () => readonly ["light" | "dark", typeof setSchemeSetting];
|
|
7
|
-
export declare function useSchemeSetting(): readonly [{
|
|
8
|
-
setting: SchemeSetting;
|
|
9
|
-
scheme: "light" | "dark";
|
|
10
|
-
}, typeof setSchemeSetting];
|
|
11
|
-
export declare function setSchemeSetting(next: SchemeSetting): void;
|
|
1
|
+
import type { Scheme } from './systemScheme';
|
|
2
|
+
export type { Scheme } from './systemScheme';
|
|
3
|
+
export type { SchemeSetting, UserScheme } from './userScheme';
|
|
4
|
+
export { getSystemScheme, useSystemScheme } from './systemScheme';
|
|
5
|
+
export { getUserScheme, onUserSchemeChange, setUserScheme, useUserScheme } from './userScheme';
|
|
12
6
|
export declare function SchemeProvider({ children, getClassName, }: {
|
|
13
7
|
children: any;
|
|
14
|
-
getClassName?: (name:
|
|
8
|
+
getClassName?: (name: Scheme) => string;
|
|
15
9
|
}): import("react/jsx-runtime").JSX.Element;
|
|
16
|
-
export declare
|
|
17
|
-
color
|
|
10
|
+
export declare function MetaTheme({ color, darkColor, lightColor, }: {
|
|
11
|
+
color?: string;
|
|
18
12
|
darkColor: string;
|
|
19
13
|
lightColor: string;
|
|
20
|
-
})
|
|
14
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
21
15
|
//# sourceMappingURL=index.d.ts.map
|
package/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAI5C,YAAY,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAG7D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAI9F,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,YAAoC,GACrC,EAAE;IACD,QAAQ,EAAE,GAAG,CAAA;IACb,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CACxC,2CAmCA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,SAAS,EACT,UAAU,GACX,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB,2CAyBA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemScheme.d.ts","sourceRoot":"","sources":["../src/systemScheme.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,MAAM,CAAA;AAOrC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAWxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemScheme.native.d.ts","sourceRoot":"","sources":["../src/systemScheme.native.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,MAAM,CAAA;AAErC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAWxC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Scheme } from './systemScheme';
|
|
2
|
+
export type SchemeSetting = 'system' | 'light' | 'dark';
|
|
3
|
+
export type UserScheme = {
|
|
4
|
+
/** The user's preference: 'system', 'light', or 'dark' */
|
|
5
|
+
setting: SchemeSetting;
|
|
6
|
+
/** The resolved scheme: 'light' or 'dark' */
|
|
7
|
+
value: Scheme;
|
|
8
|
+
/** Update the scheme setting */
|
|
9
|
+
set: (setting: SchemeSetting) => void;
|
|
10
|
+
};
|
|
11
|
+
type SchemeListener = (setting: SchemeSetting, value: Scheme) => void;
|
|
12
|
+
export declare function setUserScheme(setting: SchemeSetting): void;
|
|
13
|
+
export declare function getUserScheme(): {
|
|
14
|
+
setting: SchemeSetting;
|
|
15
|
+
value: Scheme;
|
|
16
|
+
};
|
|
17
|
+
export declare function onUserSchemeChange(listener: SchemeListener): () => void;
|
|
18
|
+
export declare function useUserScheme(): UserScheme;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=userScheme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userScheme.d.ts","sourceRoot":"","sources":["../src/userScheme.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAE7D,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;AAEvD,MAAM,MAAM,UAAU,GAAG;IACvB,0DAA0D;IAC1D,OAAO,EAAE,aAAa,CAAA;IACtB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,gCAAgC;IAChC,GAAG,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAA;CACtC,CAAA;AAED,KAAK,cAAc,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;AAoFrE,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,QAKnD;AAED,wBAAgB,aAAa,IAAI;IAAE,OAAO,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAEzE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,cAM1D;AAED,wBAAgB,aAAa,IAAI,UAAU,CA6B1C"}
|