@vxrn/color-scheme 1.13.3 → 1.13.4
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 -25
- package/dist/cjs/index.native.js +34 -16
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/userScheme.cjs +47 -17
- package/dist/cjs/userScheme.native.js +53 -20
- package/dist/cjs/userScheme.native.js.map +1 -1
- package/dist/esm/index.js +35 -26
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +35 -26
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +35 -17
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/userScheme.mjs +46 -18
- package/dist/esm/userScheme.mjs.map +1 -1
- package/dist/esm/userScheme.native.js +52 -21
- package/dist/esm/userScheme.native.js.map +1 -1
- package/package.json +2 -2
- package/src/index.tsx +52 -30
- package/src/userScheme.ts +71 -16
- package/types/index.d.ts +3 -1
- package/types/index.d.ts.map +1 -1
- package/types/userScheme.d.ts +7 -0
- package/types/userScheme.d.ts.map +1 -1
package/src/userScheme.ts
CHANGED
|
@@ -19,6 +19,54 @@ type SchemeListener = (setting: SchemeSetting, value: Scheme) => void
|
|
|
19
19
|
const listeners = new Set<SchemeListener>()
|
|
20
20
|
const storageKey = 'vxrn-scheme'
|
|
21
21
|
|
|
22
|
+
// force scheme: when set, locks the scheme and ignores user/system preferences
|
|
23
|
+
let _forceScheme: Scheme | null = null
|
|
24
|
+
|
|
25
|
+
function notifyListeners() {
|
|
26
|
+
listeners.forEach((listener) => {
|
|
27
|
+
listener(currentSetting, currentValue)
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function restoreUnforcedScheme() {
|
|
32
|
+
if (typeof localStorage !== 'undefined') {
|
|
33
|
+
const stored = localStorage.getItem(storageKey) as SchemeSetting | null
|
|
34
|
+
if (stored) {
|
|
35
|
+
currentSetting = stored
|
|
36
|
+
currentValue = stored === 'system' ? resolveValue('system') : stored
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
currentSetting = 'system'
|
|
42
|
+
currentValue = resolveValue('system')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Lock the color scheme to a fixed value. When set, user preferences and system
|
|
47
|
+
* changes are ignored, and `setUserScheme` becomes a no-op.
|
|
48
|
+
* Pass `null` to clear the force and restore normal behavior.
|
|
49
|
+
*/
|
|
50
|
+
export function setForceScheme(scheme: Scheme | null) {
|
|
51
|
+
const wasForced = _forceScheme
|
|
52
|
+
|
|
53
|
+
if (wasForced === scheme) return
|
|
54
|
+
|
|
55
|
+
_forceScheme = scheme
|
|
56
|
+
|
|
57
|
+
if (scheme) {
|
|
58
|
+
currentSetting = scheme
|
|
59
|
+
currentValue = scheme
|
|
60
|
+
} else if (wasForced) {
|
|
61
|
+
restoreUnforcedScheme()
|
|
62
|
+
startWebListener()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function getForceScheme(): Scheme | null {
|
|
67
|
+
return _forceScheme
|
|
68
|
+
}
|
|
69
|
+
|
|
22
70
|
// eagerly init from localStorage on module load (native only - web uses effect for SSR)
|
|
23
71
|
function getInitialSetting(): SchemeSetting {
|
|
24
72
|
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
@@ -89,17 +137,17 @@ function resolveValue(setting: SchemeSetting): Scheme {
|
|
|
89
137
|
|
|
90
138
|
// Only update the resolved value when system theme changes (don't change setting)
|
|
91
139
|
function updateValueFromSystem() {
|
|
140
|
+
if (_forceScheme) return
|
|
92
141
|
const value = resolveValue('system')
|
|
93
142
|
if (value !== currentValue) {
|
|
94
143
|
currentValue = value
|
|
95
144
|
// don't call Appearance.setColorScheme when following system - it breaks the listener
|
|
96
|
-
|
|
97
|
-
l(currentSetting, currentValue)
|
|
98
|
-
})
|
|
145
|
+
notifyListeners()
|
|
99
146
|
}
|
|
100
147
|
}
|
|
101
148
|
|
|
102
149
|
function updateScheme(setting: SchemeSetting) {
|
|
150
|
+
if (_forceScheme) return
|
|
103
151
|
const value = setting === 'system' ? resolveValue('system') : setting
|
|
104
152
|
|
|
105
153
|
if (value !== currentValue || currentSetting !== setting) {
|
|
@@ -117,9 +165,7 @@ function updateScheme(setting: SchemeSetting) {
|
|
|
117
165
|
}
|
|
118
166
|
}
|
|
119
167
|
|
|
120
|
-
|
|
121
|
-
l(currentSetting, currentValue)
|
|
122
|
-
})
|
|
168
|
+
notifyListeners()
|
|
123
169
|
}
|
|
124
170
|
}
|
|
125
171
|
|
|
@@ -130,6 +176,7 @@ function updateScheme(setting: SchemeSetting) {
|
|
|
130
176
|
* @param setting - 'system', 'light', or 'dark'
|
|
131
177
|
*/
|
|
132
178
|
export function setUserScheme(setting: SchemeSetting) {
|
|
179
|
+
if (_forceScheme) return
|
|
133
180
|
if (typeof localStorage !== 'undefined') {
|
|
134
181
|
localStorage.setItem(storageKey, setting)
|
|
135
182
|
}
|
|
@@ -142,6 +189,7 @@ export function setUserScheme(setting: SchemeSetting) {
|
|
|
142
189
|
* @returns Object with setting and resolved value
|
|
143
190
|
*/
|
|
144
191
|
export function getUserScheme(): { setting: SchemeSetting; value: Scheme } {
|
|
192
|
+
if (_forceScheme) return { setting: _forceScheme, value: _forceScheme }
|
|
145
193
|
return { setting: currentSetting, value: currentValue }
|
|
146
194
|
}
|
|
147
195
|
|
|
@@ -174,31 +222,38 @@ export function onUserSchemeChange(listener: SchemeListener) {
|
|
|
174
222
|
*/
|
|
175
223
|
export function useUserScheme(): UserScheme {
|
|
176
224
|
const [state, setState] = useState(() => getUserScheme())
|
|
225
|
+
const snapshot = getUserScheme()
|
|
226
|
+
const resolvedState =
|
|
227
|
+
state.setting === snapshot.setting && state.value === snapshot.value
|
|
228
|
+
? state
|
|
229
|
+
: snapshot
|
|
177
230
|
|
|
178
231
|
useIsomorphicLayoutEffect(() => {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
232
|
+
if (!_forceScheme) {
|
|
233
|
+
// restore from localStorage on mount
|
|
234
|
+
if (typeof localStorage !== 'undefined') {
|
|
235
|
+
const stored = localStorage.getItem(storageKey) as SchemeSetting | null
|
|
236
|
+
if (stored) {
|
|
237
|
+
updateScheme(stored)
|
|
238
|
+
}
|
|
184
239
|
}
|
|
240
|
+
startWebListener()
|
|
185
241
|
}
|
|
186
242
|
|
|
243
|
+
// always subscribe so force→unforce transitions propagate via setForceScheme(null)
|
|
187
244
|
const dispose = onUserSchemeChange((setting, value) => {
|
|
188
245
|
setState({ setting, value })
|
|
189
246
|
})
|
|
190
247
|
|
|
191
|
-
startWebListener()
|
|
192
|
-
|
|
193
248
|
return dispose
|
|
194
249
|
}, [])
|
|
195
250
|
|
|
196
251
|
return useMemo(
|
|
197
252
|
() => ({
|
|
198
|
-
setting:
|
|
199
|
-
value:
|
|
253
|
+
setting: resolvedState.setting,
|
|
254
|
+
value: resolvedState.value,
|
|
200
255
|
set: setUserScheme,
|
|
201
256
|
}),
|
|
202
|
-
[
|
|
257
|
+
[resolvedState.setting, resolvedState.value]
|
|
203
258
|
)
|
|
204
259
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -3,11 +3,13 @@ export type { Scheme } from './systemScheme';
|
|
|
3
3
|
export type { SchemeSetting, UserScheme } from './userScheme';
|
|
4
4
|
export { getSystemScheme, useSystemScheme } from './systemScheme';
|
|
5
5
|
export { getUserScheme, onUserSchemeChange, setUserScheme, useUserScheme, } from './userScheme';
|
|
6
|
-
export declare function SchemeProvider({ children, getClassName, defaultScheme, }: {
|
|
6
|
+
export declare function SchemeProvider({ children, getClassName, defaultScheme, forceScheme, }: {
|
|
7
7
|
children: any;
|
|
8
8
|
getClassName?: (name: Scheme) => string;
|
|
9
9
|
/** Force a default scheme when no user preference is stored. Without this, falls back to system preference. */
|
|
10
10
|
defaultScheme?: Scheme;
|
|
11
|
+
/** Lock the scheme to this value. Ignores user preference, system preference, and localStorage. Prevents hydration flicker. */
|
|
12
|
+
forceScheme?: Scheme;
|
|
11
13
|
}): import("react/jsx-runtime").JSX.Element;
|
|
12
14
|
export declare function MetaTheme({ color, darkColor, lightColor, }: {
|
|
13
15
|
color?: string;
|
package/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAS5C,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,EACL,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,MAAM,cAAc,CAAA;AAIrB,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,YAAoC,EACpC,aAAa,EACb,WAAW,GACZ,EAAE;IACD,QAAQ,EAAE,GAAG,CAAA;IACb,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IACvC,+GAA+G;IAC/G,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,+HAA+H;IAC/H,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,2CAmEA;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,2CA0BA"}
|
package/types/userScheme.d.ts
CHANGED
|
@@ -9,6 +9,13 @@ export type UserScheme = {
|
|
|
9
9
|
set: (setting: SchemeSetting) => void;
|
|
10
10
|
};
|
|
11
11
|
type SchemeListener = (setting: SchemeSetting, value: Scheme) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Lock the color scheme to a fixed value. When set, user preferences and system
|
|
14
|
+
* changes are ignored, and `setUserScheme` becomes a no-op.
|
|
15
|
+
* Pass `null` to clear the force and restore normal behavior.
|
|
16
|
+
*/
|
|
17
|
+
export declare function setForceScheme(scheme: Scheme | null): void;
|
|
18
|
+
export declare function getForceScheme(): Scheme | null;
|
|
12
19
|
/**
|
|
13
20
|
* Imperatively set the user's color scheme preference.
|
|
14
21
|
* Persists to localStorage and updates all listeners.
|
|
@@ -1 +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;
|
|
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;AA4BrE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,QAcnD;AAED,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAE9C;AAwGD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,QAMnD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI;IAAE,OAAO,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAGzE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,cAM1D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAoC1C"}
|