@sigx/lynx-appearance 0.4.1
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/LICENSE +21 -0
- package/android/com/sigx/appearance/AppearanceModule.kt +160 -0
- package/android/com/sigx/appearance/AppearancePublisher.kt +113 -0
- package/dist/globals.d.ts +21 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +25 -0
- package/dist/globals.js.map +1 -0
- package/dist/hooks.d.ts +25 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +38 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/injectable.d.ts +16 -0
- package/dist/injectable.d.ts.map +1 -0
- package/dist/injectable.js +10 -0
- package/dist/injectable.js.map +1 -0
- package/dist/provider.d.ts +27 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +59 -0
- package/dist/provider.js.map +1 -0
- package/dist/setters.d.ts +58 -0
- package/dist/setters.d.ts.map +1 -0
- package/dist/setters.js +87 -0
- package/dist/setters.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/ios/AppearanceModule.swift +130 -0
- package/ios/AppearancePublisher.swift +86 -0
- package/package.json +61 -0
- package/signalx-module.json +22 -0
- package/src/globals.ts +40 -0
- package/src/hooks.ts +46 -0
- package/src/index.ts +33 -0
- package/src/injectable.ts +20 -0
- package/src/provider.tsx +89 -0
- package/src/setters.ts +87 -0
- package/src/types.ts +25 -0
package/src/setters.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { callAsync, isModuleAvailable } from '@sigx/lynx-core';
|
|
2
|
+
import type { SetterResult, SystemBarStyle, SystemBarsStyleInput } from './types.js';
|
|
3
|
+
|
|
4
|
+
const MODULE = 'Appearance';
|
|
5
|
+
|
|
6
|
+
const UNSUPPORTED: SetterResult = { ok: false, reason: 'unsupported' };
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Set the status-bar *content* tint (clock + icons).
|
|
10
|
+
*
|
|
11
|
+
* - `'light'` = light content (white-ish icons) — use when behind a dark theme.
|
|
12
|
+
* - `'dark'` = dark content — use when behind a light theme.
|
|
13
|
+
*
|
|
14
|
+
* On iOS the host VC must forward `preferredStatusBarStyle` to
|
|
15
|
+
* `AppearanceModule.preferredStatusBarStyle` for this to take effect — the
|
|
16
|
+
* lynx-cli iOS template wires that automatically.
|
|
17
|
+
*
|
|
18
|
+
* Resolves `{ ok: false, reason: 'unsupported' }` (never rejects) when the
|
|
19
|
+
* native module isn't registered — typical in web preview, SSR, tests, or
|
|
20
|
+
* apps that don't link the module. Fire-and-forget callers can therefore
|
|
21
|
+
* `void setStatusBarStyle(...)` without risking unhandled rejections.
|
|
22
|
+
*/
|
|
23
|
+
export function setStatusBarStyle(style: SystemBarStyle): Promise<SetterResult> {
|
|
24
|
+
if (!isAvailable()) return Promise.resolve(UNSUPPORTED);
|
|
25
|
+
return callAsync<SetterResult>(MODULE, 'setStatusBarStyle', { style });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Android only — set the status-bar background color. Pass `null` (or
|
|
30
|
+
* omit / pass `'transparent'`) to clear. iOS resolves `{ ok: false,
|
|
31
|
+
* reason: 'unsupported' }` since iOS has no separate status-bar background.
|
|
32
|
+
*
|
|
33
|
+
* On Android 15+ (API 35) edge-to-edge is enforced and this call is a no-op
|
|
34
|
+
* at the system level — callers should overlay their own background view
|
|
35
|
+
* inside the safe-area top padding.
|
|
36
|
+
*
|
|
37
|
+
* Resolves `{ ok: false, reason: 'unsupported' }` (never rejects) when the
|
|
38
|
+
* native module isn't registered. See `setStatusBarStyle` for the rationale.
|
|
39
|
+
*/
|
|
40
|
+
export function setStatusBarBackgroundColor(color: string | null): Promise<SetterResult> {
|
|
41
|
+
if (!isAvailable()) return Promise.resolve(UNSUPPORTED);
|
|
42
|
+
return callAsync<SetterResult>(MODULE, 'setStatusBarBackgroundColor', { color });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Android only — set the navigation-bar content tint + optional background.
|
|
47
|
+
* iOS resolves `{ ok: false, reason: 'unsupported' }` since there's no
|
|
48
|
+
* separate navigation bar.
|
|
49
|
+
*
|
|
50
|
+
* Resolves `{ ok: false, reason: 'unsupported' }` (never rejects) when the
|
|
51
|
+
* native module isn't registered. See `setStatusBarStyle` for the rationale.
|
|
52
|
+
*/
|
|
53
|
+
export function setNavigationBarStyle(opts: { style: SystemBarStyle; color?: string }): Promise<SetterResult> {
|
|
54
|
+
if (!isAvailable()) return Promise.resolve(UNSUPPORTED);
|
|
55
|
+
return callAsync<SetterResult>(MODULE, 'setNavigationBarStyle', opts);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Convenience: apply status-bar tint + (optionally) status-bar background +
|
|
60
|
+
* nav-bar tint in one call. Resolves to the aggregate result — `ok: false`
|
|
61
|
+
* if any leg returned a non-`unsupported` failure, with the first such
|
|
62
|
+
* failure's reason. `unsupported` legs (e.g. status-bar background on iOS)
|
|
63
|
+
* are intentionally ignored so a partially-supported platform can still
|
|
64
|
+
* report success for the legs that do apply.
|
|
65
|
+
*
|
|
66
|
+
* Fields are optional; omitting any leaves that surface untouched. Order is
|
|
67
|
+
* deterministic (statusBar → statusBarBackground → navigationBar) so the
|
|
68
|
+
* resolved reason on partial failure is unambiguous.
|
|
69
|
+
*/
|
|
70
|
+
export async function setSystemBarsStyle(opts: SystemBarsStyleInput): Promise<SetterResult> {
|
|
71
|
+
if (!isAvailable()) return UNSUPPORTED;
|
|
72
|
+
let firstFailure: SetterResult | undefined;
|
|
73
|
+
const record = (r: SetterResult): void => {
|
|
74
|
+
if (!r.ok && !firstFailure && r.reason !== 'unsupported') firstFailure = r;
|
|
75
|
+
};
|
|
76
|
+
if (opts.statusBar) record(await setStatusBarStyle(opts.statusBar));
|
|
77
|
+
if (opts.statusBarBackground !== undefined) {
|
|
78
|
+
record(await setStatusBarBackgroundColor(opts.statusBarBackground));
|
|
79
|
+
}
|
|
80
|
+
if (opts.navigationBar) record(await setNavigationBarStyle(opts.navigationBar));
|
|
81
|
+
return firstFailure ?? { ok: true };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Quick check whether the native Appearance module is registered. */
|
|
85
|
+
export function isAvailable(): boolean {
|
|
86
|
+
return isModuleAvailable(MODULE);
|
|
87
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** The two color schemes the platform reports. iOS `unspecified` and
|
|
2
|
+
* Android `UI_MODE_NIGHT_UNDEFINED` both collapse to `'light'` at the
|
|
3
|
+
* native publisher boundary so JS only ever sees these two values. */
|
|
4
|
+
export type ColorScheme = 'light' | 'dark';
|
|
5
|
+
|
|
6
|
+
/** Tint of system-bar *content* (clock, icons), not its background. */
|
|
7
|
+
export type SystemBarStyle = 'light' | 'dark';
|
|
8
|
+
|
|
9
|
+
/** Result envelope returned by every native setter. */
|
|
10
|
+
export interface SetterResult {
|
|
11
|
+
ok: boolean;
|
|
12
|
+
/** Present when `ok === false` — `'unsupported'` on iOS for nav-bar and
|
|
13
|
+
* status-bar-background calls, or an Android failure message. */
|
|
14
|
+
reason?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Argument to `setSystemBarsStyle` — partial; omitted fields are left alone. */
|
|
18
|
+
export interface SystemBarsStyleInput {
|
|
19
|
+
/** Status-bar content tint. `'light'` = light icons (legible on dark bg). */
|
|
20
|
+
statusBar?: SystemBarStyle;
|
|
21
|
+
/** Android only — status-bar background color. `null` clears (transparent). */
|
|
22
|
+
statusBarBackground?: string | null;
|
|
23
|
+
/** Android only — navigation-bar tint + optional background. */
|
|
24
|
+
navigationBar?: { style: SystemBarStyle; color?: string };
|
|
25
|
+
}
|