@forthtilliath/react-native-kit 0.18.0 → 0.20.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.
Files changed (37) hide show
  1. package/README.md +60 -16
  2. package/dist/components/picker/PhotoPicker.d.ts +22 -29
  3. package/dist/components/picker/PhotoPicker.d.ts.map +1 -1
  4. package/dist/components/picker/PhotoPicker.js +49 -81
  5. package/dist/components/picker/PhotoPicker.styles.d.ts +63 -0
  6. package/dist/components/picker/PhotoPicker.styles.d.ts.map +1 -0
  7. package/dist/components/picker/PhotoPicker.styles.js +59 -0
  8. package/dist/components/picker/QuantityStepper.d.ts +32 -31
  9. package/dist/components/picker/QuantityStepper.d.ts.map +1 -1
  10. package/dist/components/picker/QuantityStepper.js +39 -69
  11. package/dist/components/picker/QuantityStepper.styles.d.ts +59 -0
  12. package/dist/components/picker/QuantityStepper.styles.d.ts.map +1 -0
  13. package/dist/components/picker/QuantityStepper.styles.js +46 -0
  14. package/dist/components/settings/UpdateSettingsScreen.d.ts +5 -1
  15. package/dist/components/settings/UpdateSettingsScreen.d.ts.map +1 -1
  16. package/dist/components/settings/UpdateSettingsScreen.js +3 -3
  17. package/dist/components/settings/UpdateSettingsScreen.styles.d.ts +2 -0
  18. package/dist/components/settings/UpdateSettingsScreen.styles.d.ts.map +1 -1
  19. package/dist/components/theme/BackgroundPicker.d.ts +46 -0
  20. package/dist/components/theme/BackgroundPicker.d.ts.map +1 -0
  21. package/dist/components/theme/BackgroundPicker.js +79 -0
  22. package/dist/components/theme/findBackground.d.ts +20 -0
  23. package/dist/components/theme/findBackground.d.ts.map +1 -0
  24. package/dist/components/theme/findBackground.js +12 -0
  25. package/dist/components/theme/index.d.ts +2 -0
  26. package/dist/components/theme/index.d.ts.map +1 -1
  27. package/dist/components/theme/index.js +2 -0
  28. package/dist/hooks/index.d.ts +1 -0
  29. package/dist/hooks/index.d.ts.map +1 -1
  30. package/dist/hooks/index.js +1 -0
  31. package/dist/hooks/useViewShare.d.ts +39 -0
  32. package/dist/hooks/useViewShare.d.ts.map +1 -0
  33. package/dist/hooks/useViewShare.js +75 -0
  34. package/dist/utils/helpers/shareViewAsImage.d.ts +5 -3
  35. package/dist/utils/helpers/shareViewAsImage.d.ts.map +1 -1
  36. package/dist/utils/helpers/shareViewAsImage.js +3 -1
  37. package/package.json +8 -8
@@ -0,0 +1,75 @@
1
+ import { useRef, useState } from "react";
2
+ import { Alert } from "react-native";
3
+ import { useKitLocale } from "../i18n/locale.js";
4
+ import { shareViewAsImage, } from "../utils/helpers/shareViewAsImage.js";
5
+ const defaultErrorLabels = {
6
+ fr: {
7
+ errorTitle: "Partage impossible",
8
+ errorMessage: "L'image n'a pas pu être créée.",
9
+ },
10
+ en: {
11
+ errorTitle: "Couldn't share",
12
+ errorMessage: "The image couldn't be created.",
13
+ },
14
+ };
15
+ /** Resolves once React has rendered the last state change and native drew it. */
16
+ function nextFrames() {
17
+ return new Promise((resolve) => {
18
+ requestAnimationFrame(() => {
19
+ requestAnimationFrame(() => {
20
+ resolve();
21
+ });
22
+ });
23
+ });
24
+ }
25
+ /**
26
+ * Shares as an image a view rendered on demand (a scoreboard, a summary card
27
+ * that isn't on screen): `capturing` is `true` while the capture runs — the
28
+ * screen mounts the view attached to `ref` (off screen, `collapsable={false}`)
29
+ * only meanwhile — and `share()` waits two frames for it to be drawn before
30
+ * capturing it with {@link shareViewAsImage}. A second `share()` while one is
31
+ * running is ignored.
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * const ranking = useViewShare({ dialogTitle: "Partager le classement" });
36
+ *
37
+ * <Button title="Partager" onPress={() => void ranking.share()} />
38
+ * {ranking.capturing ? (
39
+ * <View ref={ranking.ref} collapsable={false} style={offScreen}>
40
+ * <RankingCard />
41
+ * </View>
42
+ * ) : null}
43
+ * ```
44
+ */
45
+ export function useViewShare({ onError, errorTitle, errorMessage, ...options } = {}) {
46
+ const ref = useRef(null);
47
+ const [capturing, setCapturing] = useState(false);
48
+ // Ahead of `capturing`, which only changes on the next render.
49
+ const busyRef = useRef(false);
50
+ const locale = useKitLocale(options.locale);
51
+ const defaults = defaultErrorLabels[locale];
52
+ async function share() {
53
+ if (busyRef.current)
54
+ return;
55
+ busyRef.current = true;
56
+ setCapturing(true);
57
+ try {
58
+ await nextFrames();
59
+ await shareViewAsImage(ref, { ...options, locale });
60
+ }
61
+ catch (error) {
62
+ if (onError)
63
+ onError(error);
64
+ else
65
+ Alert.alert(errorTitle ?? defaults.errorTitle, error instanceof Error && error.message
66
+ ? error.message
67
+ : (errorMessage ?? defaults.errorMessage));
68
+ }
69
+ finally {
70
+ busyRef.current = false;
71
+ setCapturing(false);
72
+ }
73
+ }
74
+ return { ref, capturing, share };
75
+ }
@@ -1,4 +1,4 @@
1
- import type { RefObject } from "react";
1
+ import type { ComponentRef, RefObject } from "react";
2
2
  import type { View } from "react-native";
3
3
  import { type ShareFileOptions } from "./shareFile.js";
4
4
  export type ShareViewAsImageOptions = Omit<ShareFileOptions, "mimeType"> & {
@@ -12,10 +12,12 @@ export type ShareViewAsImageOptions = Omit<ShareFileOptions, "mimeType"> & {
12
12
  * module is known to be there: on a binary built without it, only this
13
13
  * feature fails — with a user-facing `Error` — instead of the whole screen.
14
14
  *
15
- * @param view - Ref of the view to capture (`collapsable={false}` on Android).
15
+ * @param view - Ref of the view to capture (`collapsable={false}` on Android),
16
+ * as `useRef<ComponentRef<typeof View>>(null)` gives — `View` is the
17
+ * component, not its instance type.
16
18
  * @param options - See {@link ShareViewAsImageOptions} and `shareFile`.
17
19
  * @example
18
20
  * await shareViewAsImage(rankingRef, { dialogTitle: "Partager le classement" });
19
21
  */
20
- export declare function shareViewAsImage(view: RefObject<View | null>, { captureUnavailableMessage, ...options }?: ShareViewAsImageOptions): Promise<void>;
22
+ export declare function shareViewAsImage(view: RefObject<ComponentRef<typeof View> | null>, { captureUnavailableMessage, ...options }?: ShareViewAsImageOptions): Promise<void>;
21
23
  //# sourceMappingURL=shareViewAsImage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shareViewAsImage.d.ts","sourceRoot":"","sources":["../../../src/utils/helpers/shareViewAsImage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAKzC,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElE,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,GAAG;IACzE,wEAAwE;IACxE,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAOF;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,EAC5B,EAAE,yBAAyB,EAAE,GAAG,OAAO,EAAE,GAAE,uBAA4B,GACtE,OAAO,CAAC,IAAI,CAAC,CAcf"}
1
+ {"version":3,"file":"shareViewAsImage.d.ts","sourceRoot":"","sources":["../../../src/utils/helpers/shareViewAsImage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAKzC,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElE,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,GAAG;IACzE,wEAAwE;IACxE,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAOF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,CAAC,YAAY,CAAC,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,EACjD,EAAE,yBAAyB,EAAE,GAAG,OAAO,EAAE,GAAE,uBAA4B,GACtE,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -12,7 +12,9 @@ const defaultCaptureUnavailableMessages = {
12
12
  * module is known to be there: on a binary built without it, only this
13
13
  * feature fails — with a user-facing `Error` — instead of the whole screen.
14
14
  *
15
- * @param view - Ref of the view to capture (`collapsable={false}` on Android).
15
+ * @param view - Ref of the view to capture (`collapsable={false}` on Android),
16
+ * as `useRef<ComponentRef<typeof View>>(null)` gives — `View` is the
17
+ * component, not its instance type.
16
18
  * @param options - See {@link ShareViewAsImageOptions} and `shareFile`.
17
19
  * @example
18
20
  * await shareViewAsImage(rankingRef, { dialogTitle: "Partager le classement" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forthtilliath/react-native-kit",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",
@@ -22,7 +22,7 @@
22
22
  "./*": "./dist/*.js"
23
23
  },
24
24
  "dependencies": {
25
- "@forthtilliath/ts-kit": "^0.13.0"
25
+ "@forthtilliath/ts-kit": "^0.15.0"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@expo/vector-icons": ">=15.0.0",
@@ -83,7 +83,7 @@
83
83
  "@size-limit/file": "^14.1.0",
84
84
  "@types/react": "^19.2.18",
85
85
  "@types/react-test-renderer": "^19.1.0",
86
- "@vitest/coverage-v8": "5.0.2",
86
+ "@vitest/coverage-v8": "5.0.5",
87
87
  "eslint": "10.7.0",
88
88
  "expo-calendar": "~57.0.5",
89
89
  "expo-file-system": "~57.0.2",
@@ -101,16 +101,16 @@
101
101
  "react-test-renderer": "19.2.3",
102
102
  "size-limit": "^14.1.0",
103
103
  "typescript": "^5.9.3",
104
- "vitest": "^5.0.2",
105
- "@forthtilliath/eslint-config": "0.9.0",
106
- "@forthtilliath/expo-release-updates-ui": "^0.4.1",
107
- "@forthtilliath/typescript-config": "0.1.1"
104
+ "vitest": "^5.0.5",
105
+ "@forthtilliath/eslint-config": "0.10.0",
106
+ "@forthtilliath/typescript-config": "0.1.1",
107
+ "@forthtilliath/expo-release-updates-ui": "^0.5.1"
108
108
  },
109
109
  "size-limit": [
110
110
  {
111
111
  "name": "dist (all modules, brotli)",
112
112
  "path": "dist/**/*.js",
113
- "limit": "44 KB"
113
+ "limit": "47 KB"
114
114
  }
115
115
  ],
116
116
  "scripts": {