@forthtilliath/expo-release-updates-ui 0.2.8 → 0.3.0

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 CHANGED
@@ -129,6 +129,8 @@ import { UpdateAvailableBanner } from "@forthtilliath/expo-release-updates-ui";
129
129
  }
130
130
  ```
131
131
 
132
+ Built-in labels are French by default; pass `locale="en"` for English (e.g. from the app's language on a bilingual app). `labels` still overrides individual strings — `title`, `action`, `dismiss`, `dismissAccessibilityLabel` — whatever the locale.
133
+
132
134
  ## Scripts
133
135
 
134
136
  ```bash
@@ -10,6 +10,8 @@ export interface UpdateAvailableBannerStyles {
10
10
  dismissButton?: StyleProp<ViewStyle>;
11
11
  dismissButtonText?: StyleProp<TextStyle>;
12
12
  }
13
+ /** Languages the banner's built-in labels are available in. */
14
+ export type UpdateBannerLocale = "fr" | "en";
13
15
  export interface UpdateAvailableBannerLabels {
14
16
  title?: (version: string) => string;
15
17
  action?: string;
@@ -22,8 +24,14 @@ export interface UpdateAvailableBannerProps {
22
24
  notes: string;
23
25
  onPress: () => void;
24
26
  onDismiss: () => void;
27
+ /** Overrides individual built-in labels, whatever the `locale`. */
25
28
  labels?: UpdateAvailableBannerLabels;
29
+ /**
30
+ * Language of the built-in labels.
31
+ * @defaultValue "fr"
32
+ */
33
+ locale?: UpdateBannerLocale;
26
34
  styles?: UpdateAvailableBannerStyles;
27
35
  }
28
- export declare function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labels, styles, }: UpdateAvailableBannerProps): import("react").JSX.Element;
36
+ export declare function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labels, locale, styles, }: UpdateAvailableBannerProps): import("react").JSX.Element;
29
37
  //# sourceMappingURL=UpdateAvailableBanner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UpdateAvailableBanner.d.ts","sourceRoot":"","sources":["../src/UpdateAvailableBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,2BAA2B,CAAC;IACrC,MAAM,CAAC,EAAE,2BAA2B,CAAC;CACtC;AAwCD,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,KAAK,EACL,OAAO,EACP,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,0BAA0B,+BA+C5B"}
1
+ {"version":3,"file":"UpdateAvailableBanner.d.ts","sourceRoot":"","sources":["../src/UpdateAvailableBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC1C;AAED,+DAA+D;AAC/D,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7C,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,mEAAmE;IACnE,MAAM,CAAC,EAAE,2BAA2B,CAAC;IACrC;;;OAGG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,MAAM,CAAC,EAAE,2BAA2B,CAAC;CACtC;AAmDD,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,KAAK,EACL,OAAO,EACP,SAAS,EACT,MAAM,EACN,MAAa,EACb,MAAM,GACP,EAAE,0BAA0B,+BA+C5B"}
@@ -28,16 +28,24 @@ const defaultStyles = {
28
28
  dismissButtonText: { fontSize: 13, color: "#6b7280" },
29
29
  };
30
30
  const defaultLabels = {
31
- title: (version) => `Version ${version} disponible`,
32
- action: "Voir",
33
- dismiss: "Fermer",
34
- dismissAccessibilityLabel: "Fermer la notification de mise à jour",
31
+ fr: {
32
+ title: (version) => `Version ${version} disponible`,
33
+ action: "Voir",
34
+ dismiss: "Fermer",
35
+ dismissAccessibilityLabel: "Fermer la notification de mise à jour",
36
+ },
37
+ en: {
38
+ title: (version) => `Version ${version} available`,
39
+ action: "View",
40
+ dismiss: "Close",
41
+ dismissAccessibilityLabel: "Dismiss the update notification",
42
+ },
35
43
  };
36
44
  // Dismissible banner announcing an available update: version, release notes
37
45
  // (via `ChangelogNotes`), and an action + dismiss button. Has no opinion on
38
46
  // what "action" does (e.g. navigate to an update screen) or on how/whether
39
47
  // dismissal is persisted — both are left entirely to the caller.
40
- export function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labels, styles, }) {
48
+ export function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labels, locale = "fr", styles, }) {
41
49
  // Style fields are merged as arrays (default, then override) so a partial
42
50
  // override only changes the properties it specifies instead of replacing
43
51
  // the whole default style object. `notes` is forwarded as-is to
@@ -58,6 +66,6 @@ export function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labe
58
66
  styles?.dismissButtonText,
59
67
  ],
60
68
  };
61
- const t = { ...defaultLabels, ...labels };
69
+ const t = { ...defaultLabels[locale], ...labels };
62
70
  return (_jsxs(View, { style: merged.container, children: [_jsxs(View, { style: merged.header, children: [_jsx(Text, { style: merged.title, children: t.title(version) }), _jsx(Pressable, { style: merged.dismissButton, onPress: onDismiss, accessibilityRole: "button", accessibilityLabel: t.dismissAccessibilityLabel, children: _jsx(Text, { style: merged.dismissButtonText, children: t.dismiss }) })] }), notes ? _jsx(ChangelogNotes, { notes: notes, styles: merged.notes }) : null, _jsx(Pressable, { style: merged.actionButton, onPress: onPress, accessibilityRole: "button", accessibilityLabel: t.action, children: _jsx(Text, { style: merged.actionButtonText, children: t.action }) })] }));
63
71
  }
@@ -1,8 +1,6 @@
1
- export interface UpdateCheckRelease {
2
- version: string;
3
- notes: string;
4
- apkUrl: string;
5
- }
1
+ import type { LatestRelease } from "@forthtilliath/expo-release-updates/githubReleases";
2
+ /** A release as returned by `fetchLatestRelease` (same shape). */
3
+ export type UpdateCheckRelease = LatestRelease;
6
4
  export type UpdateCheckState = {
7
5
  status: "idle";
8
6
  } | {
@@ -16,8 +14,11 @@ export interface UseUpdateCheckOptions {
16
14
  currentVersion: string;
17
15
  /** Fetches the latest available release, or `null` if there is none. */
18
16
  checkForUpdate: () => Promise<UpdateCheckRelease | null>;
19
- /** Positive when `a` is newer than `b`, e.g. semver comparison. */
20
- compareVersions: (a: string, b: string) => number;
17
+ /**
18
+ * Positive when `a` is newer than `b`. Defaults to
19
+ * `@forthtilliath/expo-release-updates`'s semver `compareVersions`.
20
+ */
21
+ compareVersions?: (a: string, b: string) => number;
21
22
  /** Read once on mount: when the last check ran, and which version (if any) the user already dismissed. */
22
23
  getLastCheck: () => {
23
24
  lastCheckedAt: number | null;
@@ -1 +1 @@
1
- {"version":3,"file":"useUpdateCheck.d.ts","sourceRoot":"","sources":["../src/useUpdateCheck.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GACpD;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAExB,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,cAAc,EAAE,MAAM,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACzD,mEAAmE;IACnE,eAAe,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,0GAA0G;IAC1G,YAAY,EAAE,MAAM;QAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;IACF,sGAAsG;IACtG,SAAS,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAUD,wBAAgB,cAAc,CAAC,EAC7B,cAAc,EACd,cAAc,EACd,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAuC,EACvC,GAAc,GACf,EAAE,qBAAqB,GAAG,gBAAgB,GAAG;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAyCpE"}
1
+ {"version":3,"file":"useUpdateCheck.d.ts","sourceRoot":"","sources":["../src/useUpdateCheck.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oDAAoD,CAAC;AAExF,kEAAkE;AAClE,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAE/C,MAAM,MAAM,gBAAgB,GACxB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GACpD;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAExB,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,cAAc,EAAE,MAAM,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACzD;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACnD,0GAA0G;IAC1G,YAAY,EAAE,MAAM;QAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;IACF,sGAAsG;IACtG,SAAS,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAUD,wBAAgB,cAAc,CAAC,EAC7B,cAAc,EACd,cAAc,EACd,eAAwC,EACxC,YAAY,EACZ,SAAS,EACT,aAAuC,EACvC,GAAc,GACf,EAAE,qBAAqB,GAAG,gBAAgB,GAAG;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAyCpE"}
@@ -1,4 +1,5 @@
1
1
  import { useEffect, useState } from "react";
2
+ import { compareVersions as defaultCompareVersions } from "@forthtilliath/expo-release-updates/compareVersions";
2
3
  const DEFAULT_MIN_INTERVAL_MS = 12 * 60 * 60 * 1000;
3
4
  // Checks once per mount (e.g. app launch) whether a newer release is
4
5
  // available, throttled to at most one real network check per `minIntervalMs`
@@ -6,7 +7,7 @@ const DEFAULT_MIN_INTERVAL_MS = 12 * 60 * 60 * 1000;
6
7
  // "when did we last check" / "which version did the user dismiss" is left
7
8
  // entirely to the caller (`getLastCheck`/`onChecked`, plus its own dismiss
8
9
  // handler) — this hook has no opinion on where that lives.
9
- export function useUpdateCheck({ currentVersion, checkForUpdate, compareVersions, getLastCheck, onChecked, minIntervalMs = DEFAULT_MIN_INTERVAL_MS, now = Date.now, }) {
10
+ export function useUpdateCheck({ currentVersion, checkForUpdate, compareVersions = defaultCompareVersions, getLastCheck, onChecked, minIntervalMs = DEFAULT_MIN_INTERVAL_MS, now = Date.now, }) {
10
11
  const [state, setState] = useState({ status: "idle" });
11
12
  useEffect(() => {
12
13
  const { lastCheckedAt, dismissedVersion } = getLastCheck();
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@forthtilliath/expo-release-updates-ui",
3
- "version": "0.2.8",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
+ "sideEffects": false,
5
6
  "license": "MIT",
6
7
  "publishConfig": {
7
8
  "access": "public"
@@ -21,7 +22,7 @@
21
22
  "./*": "./dist/*.js"
22
23
  },
23
24
  "dependencies": {
24
- "@forthtilliath/expo-release-updates": "0.4.7"
25
+ "@forthtilliath/expo-release-updates": "^0.5.0"
25
26
  },
26
27
  "peerDependencies": {
27
28
  "react": ">=19",
@@ -35,14 +36,14 @@
35
36
  "react-native": "0.86.0",
36
37
  "react-test-renderer": "19.2.3",
37
38
  "typescript": "^5.9.3",
38
- "vitest": "^4.1.10",
39
- "@forthtilliath/eslint-config": "0.7.0",
39
+ "vitest": "^5.0.2",
40
+ "@forthtilliath/eslint-config": "0.8.0",
40
41
  "@forthtilliath/typescript-config": "0.1.1"
41
42
  },
42
43
  "scripts": {
43
44
  "lint": "eslint . --max-warnings 0",
44
45
  "check-types": "tsc --noEmit",
45
- "clean": "rm -rf dist",
46
+ "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
46
47
  "dev": "tsc --watch -p tsconfig.build.json",
47
48
  "build": "pnpm run clean && tsc -p tsconfig.build.json",
48
49
  "test": "vitest run",