@lt-three/love3 0.1.0 → 0.1.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/README.md +40 -40
- package/dist/native/analytics/animation.d.ts +1 -1
- package/dist/native/analytics/animation.js +1 -1
- package/dist/native/analytics/chart.types.d.ts +3 -3
- package/dist/native/analytics/metric-card.d.ts +3 -3
- package/dist/native/analytics/metric-card.js +3 -3
- package/dist/native/analytics/multi-line-chart.d.ts +9 -8
- package/dist/native/analytics/multi-line-chart.js +14 -13
- package/dist/native/analytics/pie-chart.d.ts +7 -7
- package/dist/native/analytics/pie-chart.js +8 -8
- package/dist/native/analytics/single-number.d.ts +4 -4
- package/dist/native/analytics/single-number.js +2 -2
- package/dist/native/atom/avatar.d.ts +6 -6
- package/dist/native/atom/avatar.js +2 -2
- package/dist/native/atom/badge.d.ts +5 -5
- package/dist/native/atom/button.d.ts +12 -12
- package/dist/native/atom/button.js +8 -8
- package/dist/native/atom/checkbox.d.ts +4 -4
- package/dist/native/atom/checkbox.js +2 -2
- package/dist/native/atom/colored-value.d.ts +4 -4
- package/dist/native/atom/colored-value.js +4 -4
- package/dist/native/atom/image.d.ts +7 -7
- package/dist/native/atom/image.js +2 -2
- package/dist/native/atom/label.d.ts +5 -5
- package/dist/native/atom/label.js +2 -2
- package/dist/native/atom/link.d.ts +5 -5
- package/dist/native/atom/link.js +5 -5
- package/dist/native/atom/readout.d.ts +7 -7
- package/dist/native/atom/readout.js +3 -3
- package/dist/native/atom/search-input.d.ts +2 -2
- package/dist/native/atom/search-input.js +2 -2
- package/dist/native/atom/select.d.ts +14 -14
- package/dist/native/atom/select.js +8 -8
- package/dist/native/atom/separator.d.ts +2 -3
- package/dist/native/atom/separator.js +2 -3
- package/dist/native/atom/skeleton.d.ts +3 -3
- package/dist/native/atom/skeleton.js +3 -3
- package/dist/native/atom/slider.d.ts +6 -6
- package/dist/native/atom/slider.js +3 -3
- package/dist/native/atom/spinner.d.ts +4 -4
- package/dist/native/atom/spinner.js +2 -2
- package/dist/native/atom/switch.d.ts +4 -4
- package/dist/native/atom/switch.js +3 -3
- package/dist/native/atom/symbol.d.ts +7 -7
- package/dist/native/atom/symbol.js +7 -7
- package/dist/native/atom/symbol.types.d.ts +8 -8
- package/dist/native/atom/symbol.types.js +7 -7
- package/dist/native/atom/text-field.d.ts +15 -15
- package/dist/native/atom/text-field.js +5 -5
- package/dist/native/atom/theme-toggle.d.ts +7 -7
- package/dist/native/atom/theme-toggle.js +4 -4
- package/dist/native/atom/timezone-select.d.ts +5 -5
- package/dist/native/atom/timezone-select.js +4 -4
- package/dist/native/atom/typography.d.ts +2 -2
- package/dist/native/atom/typography.js +2 -2
- package/dist/native/base/button.d.ts +13 -13
- package/dist/native/base/button.js +4 -4
- package/dist/native/base/form.d.ts +15 -15
- package/dist/native/base/form.js +11 -11
- package/dist/native/base/glass-card.d.ts +3 -3
- package/dist/native/base/glass-card.js +3 -3
- package/dist/native/base/input.d.ts +8 -8
- package/dist/native/base/input.js +7 -7
- package/dist/native/base/sheet.d.ts +27 -27
- package/dist/native/base/sheet.js +15 -15
- package/dist/native/form/checkbox.d.ts +3 -3
- package/dist/native/form/checkbox.js +2 -2
- package/dist/native/form/date-picker.d.ts +9 -9
- package/dist/native/form/date-picker.js +9 -9
- package/dist/native/form/form.d.ts +5 -6
- package/dist/native/form/form.js +4 -5
- package/dist/native/form/radio-group.d.ts +5 -5
- package/dist/native/form/radio-group.js +4 -4
- package/dist/native/form/select.d.ts +2 -2
- package/dist/native/form/select.js +2 -2
- package/dist/native/form/slider.d.ts +2 -2
- package/dist/native/form/slider.js +2 -2
- package/dist/native/form/switch.d.ts +2 -2
- package/dist/native/form/switch.js +2 -2
- package/dist/native/form/text-area.d.ts +2 -2
- package/dist/native/form/text-area.js +1 -1
- package/dist/native/form/text-input.d.ts +5 -5
- package/dist/native/form/text-input.js +8 -8
- package/dist/native/layout/accordion.d.ts +5 -5
- package/dist/native/layout/accordion.js +2 -2
- package/dist/native/layout/card.d.ts +8 -8
- package/dist/native/layout/card.js +3 -3
- package/dist/native/layout/description.d.ts +2 -2
- package/dist/native/layout/description.js +2 -2
- package/dist/native/layout/error.d.ts +5 -5
- package/dist/native/layout/error.js +2 -2
- package/dist/native/layout/information.d.ts +4 -4
- package/dist/native/layout/information.js +3 -3
- package/dist/native/layout/locked.d.ts +15 -15
- package/dist/native/layout/locked.js +7 -7
- package/dist/native/layout/modal.d.ts +8 -8
- package/dist/native/layout/modal.js +5 -5
- package/dist/native/layout/not-found.d.ts +4 -4
- package/dist/native/layout/not-found.js +3 -3
- package/dist/native/layout/page-frame.d.ts +8 -8
- package/dist/native/layout/page-frame.js +3 -3
- package/dist/native/layout/panel.d.ts +5 -5
- package/dist/native/layout/panel.js +5 -5
- package/dist/native/layout/reorderable-list.d.ts +14 -14
- package/dist/native/layout/reorderable-list.js +10 -10
- package/dist/native/layout/sheet.d.ts +10 -10
- package/dist/native/layout/sheet.js +4 -4
- package/dist/native/layout/simple-dialog.d.ts +3 -3
- package/dist/native/layout/simple-dialog.js +2 -2
- package/dist/native/layout/simple-table.d.ts +18 -18
- package/dist/native/layout/simple-table.js +1 -1
- package/dist/native/layout/tab-bar.d.ts +10 -10
- package/dist/native/layout/tab-bar.js +4 -4
- package/dist/native/layout/tabs.d.ts +6 -6
- package/dist/native/layout/tabs.js +4 -4
- package/dist/native/layout/tuning-panel.d.ts +10 -10
- package/dist/native/layout/tuning-panel.js +15 -15
- package/dist/native/lib/autocomplete.d.ts +1 -1
- package/dist/native/lib/autocomplete.js +1 -1
- package/dist/native/lib/breakpoints.d.ts +3 -3
- package/dist/native/lib/breakpoints.js +3 -3
- package/dist/native/lib/chart-palette.d.ts +2 -2
- package/dist/native/lib/chart-palette.js +2 -2
- package/dist/native/lib/confirm.d.ts +15 -16
- package/dist/native/lib/confirm.js +9 -10
- package/dist/native/lib/control.d.ts +9 -9
- package/dist/native/lib/external-store.d.ts +4 -5
- package/dist/native/lib/keyboard.d.ts +7 -7
- package/dist/native/lib/keyboard.js +7 -7
- package/dist/native/lib/labels.d.ts +6 -6
- package/dist/native/lib/labels.js +6 -6
- package/dist/native/lib/loading.d.ts +3 -3
- package/dist/native/lib/loading.js +3 -3
- package/dist/native/lib/network.d.ts +5 -6
- package/dist/native/lib/network.js +5 -6
- package/dist/native/lib/scheme.d.ts +7 -7
- package/dist/native/lib/scheme.js +3 -3
- package/dist/native/lib/snackbar.d.ts +12 -13
- package/dist/native/lib/snackbar.js +7 -8
- package/dist/native/lib/theme.d.ts +15 -15
- package/dist/native/lib/theme.js +15 -15
- package/dist/native/lib/timezone.d.ts +13 -13
- package/dist/native/lib/timezone.js +13 -13
- package/dist/native/lib/token-color.d.ts +1 -1
- package/dist/native/lib/token-color.js +1 -1
- package/dist/native/lib/tuning-context.d.ts +2 -2
- package/dist/native/lib/tuning.d.ts +10 -10
- package/dist/native/lib/tuning.js +8 -8
- package/dist/native/lib/typography.d.ts +3 -3
- package/dist/native/lib/typography.js +3 -3
- package/dist/native/lib/utils.d.ts +3 -3
- package/dist/native/lib/utils.js +3 -3
- package/dist/native/once/confirm.d.ts +2 -2
- package/dist/native/once/confirm.js +2 -2
- package/dist/native/once/error-boundary.d.ts +3 -3
- package/dist/native/once/error-boundary.js +2 -2
- package/dist/native/once/loading-lock.d.ts +3 -3
- package/dist/native/once/loading-lock.js +3 -3
- package/dist/native/once/offline-banner.d.ts +6 -6
- package/dist/native/once/offline-banner.js +5 -5
- package/dist/native/once/snackbar.d.ts +7 -7
- package/dist/native/once/snackbar.js +5 -5
- package/dist/native/styles.css +21 -21
- package/dist/shared/analytics.d.ts +23 -23
- package/dist/shared/button.d.ts +1 -1
- package/dist/shared/form.d.ts +7 -7
- package/dist/shared/form.js +2 -2
- package/dist/tokens/contrast-pairs.d.ts +9 -9
- package/dist/tokens/contrast-pairs.js +10 -10
- package/dist/tokens/index.d.ts +1 -1
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/styles.gen.css +87 -87
- package/dist/tokens/tokens.gen.d.ts +2 -2
- package/dist/tokens/tokens.gen.js +2 -2
- package/dist/tuning/catalog.d.ts +8 -8
- package/dist/tuning/catalog.js +9 -9
- package/dist/tuning/color.d.ts +4 -4
- package/dist/tuning/color.js +5 -5
- package/dist/tuning/css.d.ts +13 -13
- package/dist/tuning/css.js +17 -17
- package/dist/tuning/model.d.ts +11 -11
- package/dist/tuning/model.js +11 -11
- package/dist/tuning/native.d.ts +18 -18
- package/dist/tuning/native.js +18 -18
- package/dist/tuning/schema.d.ts +15 -15
- package/dist/tuning/schema.js +22 -22
- package/dist/tuning/types.d.ts +25 -25
- package/dist/tuning/types.js +6 -6
- package/dist/web/analytics/line-chart.d.ts +6 -6
- package/dist/web/analytics/line-chart.js +3 -3
- package/dist/web/analytics/metric-card.d.ts +6 -6
- package/dist/web/analytics/metric-card.js +5 -5
- package/dist/web/analytics/multi-line-chart.d.ts +23 -23
- package/dist/web/analytics/multi-line-chart.js +33 -33
- package/dist/web/atom/avatar.d.ts +1 -1
- package/dist/web/atom/checkbox.d.ts +6 -6
- package/dist/web/atom/checkbox.js +2 -2
- package/dist/web/atom/colored-value.d.ts +4 -4
- package/dist/web/atom/colored-value.js +4 -4
- package/dist/web/atom/help.d.ts +1 -1
- package/dist/web/atom/segmented-control.d.ts +13 -14
- package/dist/web/atom/segmented-control.js +6 -7
- package/dist/web/atom/select.d.ts +7 -7
- package/dist/web/atom/select.js +5 -5
- package/dist/web/atom/slider.d.ts +3 -3
- package/dist/web/atom/slider.js +2 -2
- package/dist/web/atom/switch.d.ts +3 -3
- package/dist/web/atom/text-area.d.ts +9 -8
- package/dist/web/atom/text-area.js +9 -8
- package/dist/web/atom/text-field.d.ts +5 -4
- package/dist/web/atom/text-field.js +5 -4
- package/dist/web/atom/toggle-chip.d.ts +6 -6
- package/dist/web/atom/toggle-chip.js +4 -4
- package/dist/web/atom/tooltip.d.ts +6 -6
- package/dist/web/atom/tooltip.js +2 -2
- package/dist/web/base/accordion.js +1 -1
- package/dist/web/base/breadcrumb.d.ts +1 -1
- package/dist/web/base/breadcrumb.js +1 -1
- package/dist/web/base/card.d.ts +3 -3
- package/dist/web/base/card.js +2 -2
- package/dist/web/base/dialog.d.ts +1 -1
- package/dist/web/base/dialog.js +1 -1
- package/dist/web/base/form.d.ts +7 -7
- package/dist/web/base/form.js +5 -5
- package/dist/web/base/pagination.d.ts +5 -5
- package/dist/web/base/pagination.js +1 -1
- package/dist/web/base/sheet.d.ts +1 -1
- package/dist/web/base/sheet.js +1 -1
- package/dist/web/base/slider.d.ts +1 -1
- package/dist/web/base/sonner.d.ts +2 -2
- package/dist/web/base/sonner.js +2 -2
- package/dist/web/base/spinner.js +1 -1
- package/dist/web/form/checkbox.d.ts +8 -8
- package/dist/web/form/checkbox.js +3 -3
- package/dist/web/form/radio-group.js +3 -3
- package/dist/web/form/select.js +1 -1
- package/dist/web/form/slider.d.ts +3 -3
- package/dist/web/form/slider.js +3 -3
- package/dist/web/form/switch.d.ts +3 -3
- package/dist/web/form/switch.js +4 -4
- package/dist/web/form/text-area.js +1 -1
- package/dist/web/form/text-input.d.ts +1 -1
- package/dist/web/form/text-input.js +1 -1
- package/dist/web/layout/accordion.d.ts +5 -5
- package/dist/web/layout/accordion.js +2 -2
- package/dist/web/layout/alert-modal.d.ts +11 -11
- package/dist/web/layout/alert-modal.js +7 -7
- package/dist/web/layout/card.d.ts +1 -1
- package/dist/web/layout/information.d.ts +9 -9
- package/dist/web/layout/information.js +7 -7
- package/dist/web/layout/modal.d.ts +1 -1
- package/dist/web/layout/page-frame.d.ts +14 -14
- package/dist/web/layout/page-frame.js +7 -7
- package/dist/web/layout/scroll-area.d.ts +1 -1
- package/dist/web/layout/sheet.d.ts +4 -4
- package/dist/web/layout/simple-table.d.ts +18 -18
- package/dist/web/layout/simple-table.js +2 -2
- package/dist/web/layout/tabs.d.ts +4 -4
- package/dist/web/layout/titled-modal.d.ts +10 -11
- package/dist/web/layout/titled-modal.js +7 -8
- package/dist/web/lib/css-vars.d.ts +6 -6
- package/dist/web/lib/css-vars.js +5 -5
- package/dist/web/lib/dialog.d.ts +4 -4
- package/dist/web/lib/labels.d.ts +8 -8
- package/dist/web/lib/labels.js +8 -8
- package/dist/web/lib/modal-open-focus.d.ts +7 -7
- package/dist/web/lib/modal-open-focus.js +9 -9
- package/dist/web/lib/restore-focus.d.ts +4 -4
- package/dist/web/lib/restore-focus.js +4 -4
- package/dist/web/styles.css +33 -33
- package/package.json +2 -2
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { tokenNames, tokens } from "../../tokens/tokens.gen.js";
|
|
2
2
|
|
|
3
3
|
//#region src/native/lib/scheme.ts
|
|
4
|
-
/**
|
|
4
|
+
/** Decides the theme to actually use from the selection and the device color scheme. */
|
|
5
5
|
function resolveScheme(preference, system) {
|
|
6
6
|
if (preference === "system") return system === "dark" ? "dark" : "light";
|
|
7
7
|
return preference;
|
|
8
8
|
}
|
|
9
9
|
const isColorToken = (name) => !name.startsWith("font-") && name !== "radius";
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* The actual value of a color token. The DS owns the values (`@lt-three/love3/tokens`), and components look them up through here.
|
|
12
|
+
* The name may be in CSS variable form (`--ink-500`) or token name form (`ink-500`). Non-color tokens (typefaces, radius) are not accepted.
|
|
13
13
|
*/
|
|
14
14
|
function tokenColor(scheme, name, overlay) {
|
|
15
15
|
const key = name.startsWith("--") ? name.slice(2) : name;
|
|
@@ -3,7 +3,7 @@ import { ExternalStore } from "./external-store.js";
|
|
|
3
3
|
export type SnackbarIcon = "success" | "error" | "info" | "warning";
|
|
4
4
|
export type SnackbarAction = {
|
|
5
5
|
label: string;
|
|
6
|
-
/**
|
|
6
|
+
/** Called when pressed; the toast closes afterward (same as the sonner action on web). */
|
|
7
7
|
onPress: () => void;
|
|
8
8
|
};
|
|
9
9
|
export type SnackbarItem = {
|
|
@@ -20,27 +20,26 @@ export type SnackbarOptions = {
|
|
|
20
20
|
description?: string;
|
|
21
21
|
action?: SnackbarAction;
|
|
22
22
|
/**
|
|
23
|
-
* true
|
|
24
|
-
*
|
|
25
|
-
* `action`
|
|
23
|
+
* If true, the toast does not dismiss itself (dismiss it with `dismissSnackbar` or the close button).
|
|
24
|
+
* **Defaults to true when `action` is set** (if it disappeared before being pressed, people using a keyboard or assistive technology could not reach it in time; WCAG 2.2.1).
|
|
25
|
+
* Even with `action`, passing `duration` or an explicit `persistent: false` makes it dismiss itself.
|
|
26
26
|
*/
|
|
27
27
|
persistent?: boolean;
|
|
28
|
-
/**
|
|
28
|
+
/** Milliseconds until it dismisses itself (default 4000). Ignored when `persistent`. */
|
|
29
29
|
duration?: number;
|
|
30
30
|
};
|
|
31
|
-
/** `Snackbar
|
|
31
|
+
/** The queue read by `Snackbar`. The imperative API (`snackbar()`) writes here. */
|
|
32
32
|
export declare const snackbarStore: ExternalStore<readonly SnackbarItem[]>;
|
|
33
|
-
/** `Snackbar`
|
|
33
|
+
/** Call only while a `Snackbar` is mounted (`once/snackbar` calls it in an effect). Returns an unsubscribe function. Used for the not-mounted warning. */
|
|
34
34
|
export declare function registerSnackbarHost(): () => void;
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* 移植元の `@lt-three/native/lib/snackbar`(jotai の atom)と同じ形の API を、外部ストアで作り直した。
|
|
36
|
+
* Shows a toast. The returned id can be passed to `dismissSnackbar`.
|
|
37
|
+
* Place one `Snackbar` from `once/snackbar` at the app root (**nothing is shown without it**; a warning is logged in development.
|
|
38
|
+
* The auto-dismiss timer runs even before it is placed).
|
|
40
39
|
*/
|
|
41
40
|
export declare function snackbar(title: string, options?: SnackbarOptions): string | number;
|
|
42
|
-
/**
|
|
41
|
+
/** Dismisses the given toast. */
|
|
43
42
|
export declare function dismissSnackbar(id: string | number): void;
|
|
44
|
-
/**
|
|
43
|
+
/** Dismisses all visible toasts (and cancels all pending auto-dismiss timers). */
|
|
45
44
|
export declare function dismissAllSnackbars(): void;
|
|
46
45
|
//#endregion
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createExternalStore } from "./external-store.js";
|
|
2
2
|
|
|
3
3
|
//#region src/native/lib/snackbar.ts
|
|
4
|
-
/** `Snackbar
|
|
4
|
+
/** The queue read by `Snackbar`. The imperative API (`snackbar()`) writes here. */
|
|
5
5
|
const snackbarStore = createExternalStore([]);
|
|
6
6
|
const DEFAULT_DURATION = 4e3;
|
|
7
7
|
let sequence = 0;
|
|
8
8
|
const timers = /* @__PURE__ */ new Map();
|
|
9
9
|
let mountedHosts = 0;
|
|
10
|
-
/** `Snackbar`
|
|
10
|
+
/** Call only while a `Snackbar` is mounted (`once/snackbar` calls it in an effect). Returns an unsubscribe function. Used for the not-mounted warning. */
|
|
11
11
|
function registerSnackbarHost() {
|
|
12
12
|
mountedHosts += 1;
|
|
13
13
|
return () => {
|
|
@@ -15,10 +15,9 @@ function registerSnackbarHost() {
|
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* 移植元の `@lt-three/native/lib/snackbar`(jotai の atom)と同じ形の API を、外部ストアで作り直した。
|
|
18
|
+
* Shows a toast. The returned id can be passed to `dismissSnackbar`.
|
|
19
|
+
* Place one `Snackbar` from `once/snackbar` at the app root (**nothing is shown without it**; a warning is logged in development.
|
|
20
|
+
* The auto-dismiss timer runs even before it is placed).
|
|
22
21
|
*/
|
|
23
22
|
function snackbar(title, options) {
|
|
24
23
|
if (__DEV__ && mountedHosts === 0) console.warn("snackbar(): Snackbar がマウントされていない。アプリのルートに <Snackbar /> を 1 つ置くまで、このトーストは出ない。");
|
|
@@ -38,12 +37,12 @@ function snackbar(title, options) {
|
|
|
38
37
|
if (!persistent) timers.set(id, setTimeout(() => dismissSnackbar(id), options?.duration ?? DEFAULT_DURATION));
|
|
39
38
|
return id;
|
|
40
39
|
}
|
|
41
|
-
/**
|
|
40
|
+
/** Dismisses the given toast. */
|
|
42
41
|
function dismissSnackbar(id) {
|
|
43
42
|
clearTimer(id);
|
|
44
43
|
snackbarStore.update((items) => items.filter((candidate) => candidate.id !== id));
|
|
45
44
|
}
|
|
46
|
-
/**
|
|
45
|
+
/** Dismisses all visible toasts (and cancels all pending auto-dismiss timers). */
|
|
47
46
|
function dismissAllSnackbars() {
|
|
48
47
|
for (const timer of timers.values()) clearTimeout(timer);
|
|
49
48
|
timers.clear();
|
|
@@ -2,32 +2,32 @@ import { ActiveScheme, ThemePreference } from "./scheme.js";
|
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
3
|
//#region src/native/lib/theme.d.ts
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* The current effective theme.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* It does not return the colors themselves. Colors come from NativeWind's semantic classes
|
|
8
|
+
* (`bg-background` / `text-foreground`, etc.). Use this hook only where
|
|
9
|
+
* a native-side API (react-navigation theme, StatusBar, SF Symbols tint, chart colors, etc.)
|
|
10
|
+
* needs light/dark passed to it.
|
|
11
11
|
*/
|
|
12
12
|
export declare function useActiveScheme(): ActiveScheme;
|
|
13
13
|
export type ThemeRootProps = {
|
|
14
|
-
/**
|
|
14
|
+
/** Theme selection. Where it is stored (AsyncStorage, jotai, etc.) is up to the app; only the value is passed here. */
|
|
15
15
|
preference: ThemePreference;
|
|
16
16
|
children: ReactNode;
|
|
17
17
|
};
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* The root that applies the theme to actual rendering.
|
|
20
20
|
*
|
|
21
|
-
* `@lt-three/love3/styles.css`
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
21
|
+
* `@lt-three/love3/styles.css` defines dark tokens of the form `.dark { --paper: ...; ... }`,
|
|
22
|
+
* which are **class-based**. react-native-css compiles this class rule as is,
|
|
23
|
+
* so placing `className="dark"` on the root distributes the dark CSS variables to every descendant.
|
|
24
|
+
* This works the same way as `<html class="dark">` on web, so the tokens need not be duplicated in TS.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* It also syncs React Native's `Appearance`. Native UI outside NativeWind, such as the navigation theme and StatusBar,
|
|
27
|
+
* reads it.
|
|
28
28
|
*
|
|
29
|
-
* **web
|
|
30
|
-
*
|
|
29
|
+
* **Not used on web (react-native-web).** The web theme is owned by `<html class="dark">`
|
|
30
|
+
* (preview and vitest switch it directly).
|
|
31
31
|
*/
|
|
32
32
|
export declare function ThemeRoot({ preference, children }: ThemeRootProps): import("react").JSX.Element;
|
|
33
33
|
//#endregion
|
package/dist/native/lib/theme.js
CHANGED
|
@@ -4,15 +4,15 @@ import { Appearance, View, useColorScheme } from "react-native";
|
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
|
|
6
6
|
//#region src/native/lib/theme.tsx
|
|
7
|
-
/** `ThemeRoot`
|
|
7
|
+
/** The effective theme distributed by `ThemeRoot`. Outside `ThemeRoot` it follows the device color scheme. */
|
|
8
8
|
const SchemeContext = createContext(null);
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* The current effective theme.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* It does not return the colors themselves. Colors come from NativeWind's semantic classes
|
|
13
|
+
* (`bg-background` / `text-foreground`, etc.). Use this hook only where
|
|
14
|
+
* a native-side API (react-navigation theme, StatusBar, SF Symbols tint, chart colors, etc.)
|
|
15
|
+
* needs light/dark passed to it.
|
|
16
16
|
*/
|
|
17
17
|
function useActiveScheme() {
|
|
18
18
|
const fromRoot = useContext(SchemeContext);
|
|
@@ -20,18 +20,18 @@ function useActiveScheme() {
|
|
|
20
20
|
return fromRoot ?? resolveScheme("system", system);
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* The root that applies the theme to actual rendering.
|
|
24
24
|
*
|
|
25
|
-
* `@lt-three/love3/styles.css`
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
25
|
+
* `@lt-three/love3/styles.css` defines dark tokens of the form `.dark { --paper: ...; ... }`,
|
|
26
|
+
* which are **class-based**. react-native-css compiles this class rule as is,
|
|
27
|
+
* so placing `className="dark"` on the root distributes the dark CSS variables to every descendant.
|
|
28
|
+
* This works the same way as `<html class="dark">` on web, so the tokens need not be duplicated in TS.
|
|
29
29
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* It also syncs React Native's `Appearance`. Native UI outside NativeWind, such as the navigation theme and StatusBar,
|
|
31
|
+
* reads it.
|
|
32
32
|
*
|
|
33
|
-
* **web
|
|
34
|
-
*
|
|
33
|
+
* **Not used on web (react-native-web).** The web theme is owned by `<html class="dark">`
|
|
34
|
+
* (preview and vitest switch it directly).
|
|
35
35
|
*/
|
|
36
36
|
function ThemeRoot({ preference, children }) {
|
|
37
37
|
const system = useColorScheme();
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
//#region src/native/lib/timezone.d.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Utilities for time zones (IANA strings). Used by `atom/timezone-select`.
|
|
4
|
+
* love3 has no dependency on a shared core package, so this lives in native `lib/`
|
|
5
|
+
* (if a timezone-select is added to the web side of love3, move this to `shared/` and share it).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* Hermes
|
|
9
|
-
* `
|
|
10
|
-
*
|
|
7
|
+
* The options are not built from `Intl.supportedValuesOf("timeZone")` because the native JS engine
|
|
8
|
+
* Hermes does not have it (confirmed that the string is absent from the hermesvm binary of Hermes 250829098.0.16.
|
|
9
|
+
* `resolvedOptions().timeZone` of `Intl.DateTimeFormat` exists on both iOS and Android).
|
|
10
|
+
* Listing every zone (about 420) is unusable in a select list without search, so a fixed list is used.
|
|
11
11
|
*/
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* Major IANA time zones. Representative cities of each region, chosen from the IANA tz database.
|
|
14
|
+
* Even for values not listed here, `timeZoneOptions` always adds the device time zone and the saved value.
|
|
15
15
|
*/
|
|
16
16
|
export declare const MAJOR_TIME_ZONES: readonly string[];
|
|
17
|
-
/**
|
|
17
|
+
/** This device's time zone (IANA string). An empty string if it cannot be obtained. */
|
|
18
18
|
export declare function getDeviceTimeZone(): string;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* The list of time zone options. Adds `extra` (the device value, the saved value) to the fixed list,
|
|
21
|
+
* and returns it with duplicates and the empty string removed. Prevents a selected value not in the list from vanishing from the options and showing as empty.
|
|
22
22
|
*/
|
|
23
23
|
export declare function timeZoneOptions(...extra: string[]): string[];
|
|
24
|
-
/**
|
|
24
|
+
/** Display name. The IANA `_` is hard to read, so it is turned into a space (`America/New_York` → `America/New York`). */
|
|
25
25
|
export declare function formatTimeZoneLabel(zone: string): string;
|
|
26
26
|
//#endregion
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
//#region src/native/lib/timezone.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Utilities for time zones (IANA strings). Used by `atom/timezone-select`.
|
|
4
|
+
* love3 has no dependency on a shared core package, so this lives in native `lib/`
|
|
5
|
+
* (if a timezone-select is added to the web side of love3, move this to `shared/` and share it).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* Hermes
|
|
9
|
-
* `
|
|
10
|
-
*
|
|
7
|
+
* The options are not built from `Intl.supportedValuesOf("timeZone")` because the native JS engine
|
|
8
|
+
* Hermes does not have it (confirmed that the string is absent from the hermesvm binary of Hermes 250829098.0.16.
|
|
9
|
+
* `resolvedOptions().timeZone` of `Intl.DateTimeFormat` exists on both iOS and Android).
|
|
10
|
+
* Listing every zone (about 420) is unusable in a select list without search, so a fixed list is used.
|
|
11
11
|
*/
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* Major IANA time zones. Representative cities of each region, chosen from the IANA tz database.
|
|
14
|
+
* Even for values not listed here, `timeZoneOptions` always adds the device time zone and the saved value.
|
|
15
15
|
*/
|
|
16
16
|
const MAJOR_TIME_ZONES = [
|
|
17
17
|
"UTC",
|
|
@@ -69,7 +69,7 @@ const MAJOR_TIME_ZONES = [
|
|
|
69
69
|
"Australia/Melbourne",
|
|
70
70
|
"Pacific/Auckland"
|
|
71
71
|
];
|
|
72
|
-
/**
|
|
72
|
+
/** This device's time zone (IANA string). An empty string if it cannot be obtained. */
|
|
73
73
|
function getDeviceTimeZone() {
|
|
74
74
|
try {
|
|
75
75
|
return Intl.DateTimeFormat().resolvedOptions().timeZone ?? "";
|
|
@@ -78,15 +78,15 @@ function getDeviceTimeZone() {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
81
|
+
* The list of time zone options. Adds `extra` (the device value, the saved value) to the fixed list,
|
|
82
|
+
* and returns it with duplicates and the empty string removed. Prevents a selected value not in the list from vanishing from the options and showing as empty.
|
|
83
83
|
*/
|
|
84
84
|
function timeZoneOptions(...extra) {
|
|
85
85
|
const set = new Set(MAJOR_TIME_ZONES);
|
|
86
86
|
for (const zone of extra) if (zone) set.add(zone);
|
|
87
87
|
return [...set].sort((a, b) => a.localeCompare(b));
|
|
88
88
|
}
|
|
89
|
-
/**
|
|
89
|
+
/** Display name. The IANA `_` is hard to read, so it is turned into a space (`America/New_York` → `America/New York`). */
|
|
90
90
|
function formatTimeZoneLabel(zone) {
|
|
91
91
|
return zone.replaceAll("_", " ");
|
|
92
92
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ColorTokenName } from "./scheme.js";
|
|
2
2
|
//#region src/native/lib/token-color.d.ts
|
|
3
|
-
/**
|
|
3
|
+
/** The argument is a color token in CSS variable form (`--ink-500`). Semantic names (`--muted-foreground`) can also be looked up. Typefaces and radius are not accepted. */
|
|
4
4
|
export declare function useTokenColor(name: `--${ColorTokenName}`): string;
|
|
5
5
|
//#endregion
|
|
@@ -4,7 +4,7 @@ import { TuningTokensContext } from "./tuning-context.js";
|
|
|
4
4
|
import { useContext } from "react";
|
|
5
5
|
|
|
6
6
|
//#region src/native/lib/token-color.ts
|
|
7
|
-
/**
|
|
7
|
+
/** The argument is a color token in CSS variable form (`--ink-500`). Semantic names (`--muted-foreground`) can also be looked up. Typefaces and radius are not accepted. */
|
|
8
8
|
function useTokenColor(name) {
|
|
9
9
|
return tokenColor(useActiveScheme(), name, useContext(TuningTokensContext));
|
|
10
10
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Mode } from "../../tuning/types.js";
|
|
2
2
|
//#region src/native/lib/tuning-context.d.ts
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* TS
|
|
4
|
+
* The effective token values (separate for light and dark; references resolved) distributed by tuning (`TuningRoot`). If absent (outside `TuningRoot`), there is no tuning.
|
|
5
|
+
* `useTokenColor`, which looks up colors from TS, reads this to follow runtime overrides.
|
|
6
6
|
*/
|
|
7
7
|
export type TuningTokens = Readonly<Record<Mode, Readonly<Record<string, string>>>>;
|
|
8
8
|
export declare const TuningTokensContext: import("react").Context<Readonly<Record<Mode, Readonly<Record<string, string>>>> | null>;
|
|
@@ -2,23 +2,23 @@ import { Tuning, TuningCatalog } from "../../tuning/types.js";
|
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
3
|
//#region src/native/lib/tuning.d.ts
|
|
4
4
|
export type TuningRootProps = {
|
|
5
|
-
/**
|
|
5
|
+
/** The tuning content (the diff from the defaults; `Tuning` of `@lt-three/love3/tuning`. Where it is stored is up to the app). */
|
|
6
6
|
tuning: Tuning;
|
|
7
|
-
/**
|
|
7
|
+
/** The tuning target. Defaults to love3's generated output (`tuning/catalog.gen.ts`). */
|
|
8
8
|
catalog?: TuningCatalog;
|
|
9
9
|
children: ReactNode;
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* The root that applies tuning (runtime overrides of tokens) to descendant components. Place it **inside `ThemeRoot`** (to receive the effective theme and the dark variables).
|
|
13
13
|
*
|
|
14
|
-
* - `react-native-css
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* react-native-web
|
|
18
|
-
* - TS
|
|
19
|
-
* -
|
|
14
|
+
* - Distributes the changed colors, radius, and typefaces as CSS variables with `VariableContextProvider` from `react-native-css`. On device, what takes effect is
|
|
15
|
+
* classes that use color tokens whose values differ between light and dark (such as `bg-card`) and typefaces. Classes folded into literals at build time, such as `bg-action`,
|
|
16
|
+
* plus radius, body text size, and the targets of semantic references, **do not take effect on device** (`nativeLimits` returns an explanation.
|
|
17
|
+
* On react-native-web they are CSS variables, so everything takes effect)
|
|
18
|
+
* - Components that look up colors from TS (`useTokenColor`) read the effective values (references resolved) from `TuningTokensContext`, so **all of them follow**
|
|
19
|
+
* - With no tuning (same as the defaults), nothing changes (empty `tuning` restores the original look)
|
|
20
20
|
*
|
|
21
|
-
*
|
|
21
|
+
* Not yet verified on a real device (Expo). The README lists what was verified in react-native-web browser tests.
|
|
22
22
|
*/
|
|
23
23
|
export declare function TuningRoot({ tuning, catalog, children }: TuningRootProps): import("react").JSX.Element;
|
|
24
24
|
//#endregion
|
|
@@ -9,16 +9,16 @@ import { VariableContextProvider } from "react-native-css";
|
|
|
9
9
|
|
|
10
10
|
//#region src/native/lib/tuning.tsx
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* The root that applies tuning (runtime overrides of tokens) to descendant components. Place it **inside `ThemeRoot`** (to receive the effective theme and the dark variables).
|
|
13
13
|
*
|
|
14
|
-
* - `react-native-css
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* react-native-web
|
|
18
|
-
* - TS
|
|
19
|
-
* -
|
|
14
|
+
* - Distributes the changed colors, radius, and typefaces as CSS variables with `VariableContextProvider` from `react-native-css`. On device, what takes effect is
|
|
15
|
+
* classes that use color tokens whose values differ between light and dark (such as `bg-card`) and typefaces. Classes folded into literals at build time, such as `bg-action`,
|
|
16
|
+
* plus radius, body text size, and the targets of semantic references, **do not take effect on device** (`nativeLimits` returns an explanation.
|
|
17
|
+
* On react-native-web they are CSS variables, so everything takes effect)
|
|
18
|
+
* - Components that look up colors from TS (`useTokenColor`) read the effective values (references resolved) from `TuningTokensContext`, so **all of them follow**
|
|
19
|
+
* - With no tuning (same as the defaults), nothing changes (empty `tuning` restores the original look)
|
|
20
20
|
*
|
|
21
|
-
*
|
|
21
|
+
* Not yet verified on a real device (Expo). The README lists what was verified in react-native-web browser tests.
|
|
22
22
|
*/
|
|
23
23
|
function TuningRoot({ tuning, catalog: catalog$1 = catalog, children }) {
|
|
24
24
|
const scheme = useActiveScheme();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { TextStyle } from "react-native";
|
|
2
2
|
//#region src/native/lib/typography.d.ts
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* A style that aligns digits with equal widths (tabular).
|
|
5
5
|
*
|
|
6
|
-
* Tailwind
|
|
7
|
-
*
|
|
6
|
+
* Tailwind's `tabular-nums` (`font-variant-numeric`) cannot be expressed in className because
|
|
7
|
+
* react-native-css does not support it. For numeric displays, pass this via `style`.
|
|
8
8
|
*/
|
|
9
9
|
export declare const tabularNums: TextStyle;
|
|
10
10
|
//#endregion
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
//#region src/native/lib/typography.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* A style that aligns digits with equal widths (tabular).
|
|
4
4
|
*
|
|
5
|
-
* Tailwind
|
|
6
|
-
*
|
|
5
|
+
* Tailwind's `tabular-nums` (`font-variant-numeric`) cannot be expressed in className because
|
|
6
|
+
* react-native-css does not support it. For numeric displays, pass this via `style`.
|
|
7
7
|
*/
|
|
8
8
|
const tabularNums = { fontVariant: ["tabular-nums"] };
|
|
9
9
|
|
|
@@ -3,9 +3,9 @@ import { ClassValue } from "clsx";
|
|
|
3
3
|
//#region src/native/lib/utils.d.ts
|
|
4
4
|
export declare function cn(...inputs: ClassValue[]): string;
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* A `ReactNode` that renders nothing (`null`, `undefined`, booleans, the empty string, and arrays or `<></>` containing only those).
|
|
7
|
+
* Used to decide whether a heading or label "exists" (an empty heading such as `""` or `<></>` does not count as a name).
|
|
8
|
+
* An element (such as `<Text />`) counts as existing even if its content is empty (it is drawn). Only a Fragment is decided by its content.
|
|
9
9
|
*/
|
|
10
10
|
export declare function isBlankNode(node: ReactNode): boolean;
|
|
11
11
|
//#endregion
|
package/dist/native/lib/utils.js
CHANGED
|
@@ -7,9 +7,9 @@ function cn(...inputs) {
|
|
|
7
7
|
return twMerge(clsx(inputs));
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* A `ReactNode` that renders nothing (`null`, `undefined`, booleans, the empty string, and arrays or `<></>` containing only those).
|
|
11
|
+
* Used to decide whether a heading or label "exists" (an empty heading such as `""` or `<></>` does not count as a name).
|
|
12
|
+
* An element (such as `<Text />`) counts as existing even if its content is empty (it is drawn). Only a Fragment is decided by its content.
|
|
13
13
|
*/
|
|
14
14
|
function isBlankNode(node) {
|
|
15
15
|
if (node === null || node === void 0 || typeof node === "boolean" || node === "") return true;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//#region src/native/once/confirm.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* `confirm()
|
|
4
|
-
*
|
|
3
|
+
* The confirmation dialog invoked by `confirm()` (`lib/confirm.ts`). Place exactly one at the app root.
|
|
4
|
+
* It reads from an external store (`confirmDialogStore`).
|
|
5
5
|
*/
|
|
6
6
|
export declare function ConfirmDialog(): import("react").JSX.Element;
|
|
7
7
|
//#endregion
|
|
@@ -7,8 +7,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
7
7
|
|
|
8
8
|
//#region src/native/once/confirm.tsx
|
|
9
9
|
/**
|
|
10
|
-
* `confirm()
|
|
11
|
-
*
|
|
10
|
+
* The confirmation dialog invoked by `confirm()` (`lib/confirm.ts`). Place exactly one at the app root.
|
|
11
|
+
* It reads from an external store (`confirmDialogStore`).
|
|
12
12
|
*/
|
|
13
13
|
function ConfirmDialog() {
|
|
14
14
|
const dialog = confirmDialogStore.use();
|
|
@@ -7,15 +7,15 @@ export type ErrorBoundaryLabels = {
|
|
|
7
7
|
};
|
|
8
8
|
export type ErrorBoundaryProps = {
|
|
9
9
|
children: ReactNode;
|
|
10
|
-
/**
|
|
10
|
+
/** Text for the fallback screen. The app resolves i18n and passes it in. */
|
|
11
11
|
labels: ErrorBoundaryLabels;
|
|
12
12
|
};
|
|
13
13
|
type State = {
|
|
14
14
|
hasError: boolean;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* An error boundary wrapping the whole app. It catches rendering exceptions in the child tree and,
|
|
18
|
+
* instead of a blank-screen crash, shows a fallback with a way to recover.
|
|
19
19
|
*/
|
|
20
20
|
export declare class ErrorBoundary extends Component<ErrorBoundaryProps, State> {
|
|
21
21
|
state: State;
|
|
@@ -27,8 +27,8 @@ function ErrorFallback({ title, description, retry, onRetry }) {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* An error boundary wrapping the whole app. It catches rendering exceptions in the child tree and,
|
|
31
|
+
* instead of a blank-screen crash, shows a fallback with a way to recover.
|
|
32
32
|
*/
|
|
33
33
|
var ErrorBoundary = class extends Component {
|
|
34
34
|
constructor(..._args) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
//#region src/native/once/loading-lock.d.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* `globalLoading(true)
|
|
5
|
-
*
|
|
3
|
+
* An overlay that blocks interaction during global loading. Place exactly one at the app root.
|
|
4
|
+
* It appears on `globalLoading(true)` (`lib/loading.ts`) and disappears on `false`.
|
|
5
|
+
* It reads from an external store (`loadingStore`).
|
|
6
6
|
*/
|
|
7
7
|
export declare function LoadingLock(): import("react").JSX.Element;
|
|
8
8
|
//#endregion
|
|
@@ -6,9 +6,9 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
6
|
|
|
7
7
|
//#region src/native/once/loading-lock.tsx
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
* `globalLoading(true)
|
|
11
|
-
*
|
|
9
|
+
* An overlay that blocks interaction during global loading. Place exactly one at the app root.
|
|
10
|
+
* It appears on `globalLoading(true)` (`lib/loading.ts`) and disappears on `false`.
|
|
11
|
+
* It reads from an external store (`loadingStore`).
|
|
12
12
|
*/
|
|
13
13
|
function LoadingLock() {
|
|
14
14
|
const loading = loadingStore.use();
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
//#region src/native/once/offline-banner.d.ts
|
|
2
2
|
export type OfflineBannerProps = {
|
|
3
|
-
/**
|
|
3
|
+
/** The text to show. love3 does not depend on i18n, so the app resolves it and passes it in. */
|
|
4
4
|
message: string;
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* A banner permanently shown at the top of the screen while the connection is down. It disappears automatically when the connection returns.
|
|
8
|
+
* The root needs `react-native-safe-area-context`'s `SafeAreaProvider` (Expo Router includes it by default).
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* The colors are the `destructive` surface and the text on it (`paper`; the same pair as `atom/button`'s destructive).
|
|
11
|
+
* love3 has no color literals (it uses tokens), so the banner follows the theme.
|
|
12
|
+
* The state comes from `useIsOnline` in `lib/network.ts` (NetInfo; `navigator.onLine` on web). When the connection drops it is announced with `role="alert"`.
|
|
13
13
|
*/
|
|
14
14
|
export declare function OfflineBanner({ message }: OfflineBannerProps): import("react").JSX.Element | null;
|
|
15
15
|
//#endregion
|
|
@@ -6,12 +6,12 @@ import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
|
6
6
|
|
|
7
7
|
//#region src/native/once/offline-banner.tsx
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* A banner permanently shown at the top of the screen while the connection is down. It disappears automatically when the connection returns.
|
|
10
|
+
* The root needs `react-native-safe-area-context`'s `SafeAreaProvider` (Expo Router includes it by default).
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* The colors are the `destructive` surface and the text on it (`paper`; the same pair as `atom/button`'s destructive).
|
|
13
|
+
* love3 has no color literals (it uses tokens), so the banner follows the theme.
|
|
14
|
+
* The state comes from `useIsOnline` in `lib/network.ts` (NetInfo; `navigator.onLine` on web). When the connection drops it is announced with `role="alert"`.
|
|
15
15
|
*/
|
|
16
16
|
function OfflineBanner({ message }) {
|
|
17
17
|
const online = useIsOnline();
|