@react-native-vector-icons/common 12.0.0 → 12.1.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 (80) hide show
  1. package/README.md +50 -38
  2. package/lib/commonjs/create-icon-set.js +16 -58
  3. package/lib/commonjs/create-icon-set.js.map +1 -1
  4. package/lib/commonjs/create-icon-source-cache.js +0 -2
  5. package/lib/commonjs/create-icon-source-cache.js.map +1 -1
  6. package/lib/commonjs/defaults.js +9 -0
  7. package/lib/commonjs/defaults.js.map +1 -0
  8. package/lib/commonjs/dynamicLoading/dynamic-font-loading.js +8 -18
  9. package/lib/commonjs/dynamicLoading/dynamic-font-loading.js.map +1 -1
  10. package/lib/commonjs/dynamicLoading/dynamic-loading-setting.js +19 -2
  11. package/lib/commonjs/dynamicLoading/dynamic-loading-setting.js.map +1 -1
  12. package/lib/commonjs/get-image-library.js +25 -5
  13. package/lib/commonjs/get-image-library.js.map +1 -1
  14. package/lib/commonjs/get-image-source.js +58 -0
  15. package/lib/commonjs/get-image-source.js.map +1 -0
  16. package/lib/commonjs/index.js +3 -2
  17. package/lib/commonjs/index.js.map +1 -1
  18. package/lib/commonjs/scripts/common.js.map +1 -1
  19. package/lib/commonjs/scripts/updatePlist.js.map +1 -1
  20. package/lib/module/create-icon-set.js +15 -57
  21. package/lib/module/create-icon-set.js.map +1 -1
  22. package/lib/module/create-icon-source-cache.js +0 -2
  23. package/lib/module/create-icon-source-cache.js.map +1 -1
  24. package/lib/module/defaults.js +5 -0
  25. package/lib/module/defaults.js.map +1 -0
  26. package/lib/module/dynamicLoading/dynamic-font-loading.js +10 -17
  27. package/lib/module/dynamicLoading/dynamic-font-loading.js.map +1 -1
  28. package/lib/module/dynamicLoading/dynamic-loading-setting.js +15 -1
  29. package/lib/module/dynamicLoading/dynamic-loading-setting.js.map +1 -1
  30. package/lib/module/get-image-library.js +26 -5
  31. package/lib/module/get-image-library.js.map +1 -1
  32. package/lib/module/get-image-source.js +52 -0
  33. package/lib/module/get-image-source.js.map +1 -0
  34. package/lib/module/index.js +3 -2
  35. package/lib/module/index.js.map +1 -1
  36. package/lib/module/scripts/common.js.map +1 -1
  37. package/lib/module/scripts/updatePlist.js.map +1 -1
  38. package/lib/typescript/commonjs/src/create-icon-set.d.ts +0 -2
  39. package/lib/typescript/commonjs/src/create-icon-set.d.ts.map +1 -1
  40. package/lib/typescript/commonjs/src/create-icon-source-cache.d.ts +0 -1
  41. package/lib/typescript/commonjs/src/create-icon-source-cache.d.ts.map +1 -1
  42. package/lib/typescript/commonjs/src/defaults.d.ts +3 -0
  43. package/lib/typescript/commonjs/src/defaults.d.ts.map +1 -0
  44. package/lib/typescript/commonjs/src/dynamicLoading/dynamic-font-loading.d.ts.map +1 -1
  45. package/lib/typescript/commonjs/src/dynamicLoading/dynamic-loading-setting.d.ts +33 -7
  46. package/lib/typescript/commonjs/src/dynamicLoading/dynamic-loading-setting.d.ts.map +1 -1
  47. package/lib/typescript/commonjs/src/get-image-library.d.ts +4 -1
  48. package/lib/typescript/commonjs/src/get-image-library.d.ts.map +1 -1
  49. package/lib/typescript/commonjs/src/get-image-source.d.ts +11 -0
  50. package/lib/typescript/commonjs/src/get-image-source.d.ts.map +1 -0
  51. package/lib/typescript/commonjs/src/index.d.ts +4 -3
  52. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  53. package/lib/typescript/commonjs/src/scripts/common.d.ts.map +1 -1
  54. package/lib/typescript/module/src/create-icon-set.d.ts +0 -2
  55. package/lib/typescript/module/src/create-icon-set.d.ts.map +1 -1
  56. package/lib/typescript/module/src/create-icon-source-cache.d.ts +0 -1
  57. package/lib/typescript/module/src/create-icon-source-cache.d.ts.map +1 -1
  58. package/lib/typescript/module/src/defaults.d.ts +3 -0
  59. package/lib/typescript/module/src/defaults.d.ts.map +1 -0
  60. package/lib/typescript/module/src/dynamicLoading/dynamic-font-loading.d.ts.map +1 -1
  61. package/lib/typescript/module/src/dynamicLoading/dynamic-loading-setting.d.ts +33 -7
  62. package/lib/typescript/module/src/dynamicLoading/dynamic-loading-setting.d.ts.map +1 -1
  63. package/lib/typescript/module/src/get-image-library.d.ts +4 -1
  64. package/lib/typescript/module/src/get-image-library.d.ts.map +1 -1
  65. package/lib/typescript/module/src/get-image-source.d.ts +11 -0
  66. package/lib/typescript/module/src/get-image-source.d.ts.map +1 -0
  67. package/lib/typescript/module/src/index.d.ts +4 -3
  68. package/lib/typescript/module/src/index.d.ts.map +1 -1
  69. package/lib/typescript/module/src/scripts/common.d.ts.map +1 -1
  70. package/package.json +3 -3
  71. package/src/create-icon-set.tsx +22 -76
  72. package/src/create-icon-source-cache.ts +1 -3
  73. package/src/defaults.ts +2 -0
  74. package/src/dynamicLoading/dynamic-font-loading.ts +12 -17
  75. package/src/dynamicLoading/dynamic-loading-setting.ts +65 -18
  76. package/src/get-image-library.ts +30 -9
  77. package/src/get-image-source.ts +74 -0
  78. package/src/index.ts +4 -3
  79. package/src/scripts/common.ts +1 -0
  80. package/src/scripts/updatePlist.ts +1 -0
@@ -1,19 +1,35 @@
1
1
  import type { FontSource } from './types';
2
2
 
3
+ type ExpoAssetModule = {
4
+ // definition from
5
+ // https://github.com/expo/expo/blob/1f5a5991d14aad09282d1ce1612b44d30e7e7d3d/packages/expo-asset/ios/AssetModule.swift#L23
6
+ downloadAsync: (uri: string, hash: string | undefined, type: string) => Promise<string>;
7
+ };
8
+
9
+ type ExpoFontLoaderModule = {
10
+ // definition from
11
+ // https://github.com/expo/expo/blob/1f5a5991d14aad09282d1ce1612b44d30e7e7d3d/packages/expo-font/ios/FontLoaderModule.swift#L18
12
+ getLoadedFonts: () => string[];
13
+ loadAsync: (fontFamilyAlias: string, fileUri: string) => Promise<void>;
14
+ };
15
+
16
+ type ExpoFontUtilsModule = {
17
+ renderToImageAsync: (
18
+ glyph: string,
19
+ options: {
20
+ fontFamily?: string;
21
+ size?: number;
22
+ color?: number;
23
+ },
24
+ ) => Promise<string>;
25
+ };
26
+
3
27
  declare global {
4
28
  interface ExpoGlobal {
5
29
  modules: {
6
- ExpoAsset: {
7
- // definition from
8
- // https://github.com/expo/expo/blob/1f5a5991d14aad09282d1ce1612b44d30e7e7d3d/packages/expo-asset/ios/AssetModule.swift#L23
9
- downloadAsync: (uri: string, hash: string | undefined, type: string) => Promise<string>;
10
- };
11
- ExpoFontLoader: {
12
- // definition from
13
- // https://github.com/expo/expo/blob/1f5a5991d14aad09282d1ce1612b44d30e7e7d3d/packages/expo-font/ios/FontLoaderModule.swift#L18
14
- getLoadedFonts: () => string[];
15
- loadAsync: (fontFamilyAlias: string, fileUri: string) => Promise<void>;
16
- };
30
+ ExpoAsset?: ExpoAssetModule;
31
+ ExpoFontLoader?: ExpoFontLoaderModule;
32
+ ExpoFontUtils?: ExpoFontUtilsModule;
17
33
  };
18
34
  }
19
35
 
@@ -21,10 +37,45 @@ declare global {
21
37
  var expo: ExpoGlobal | undefined;
22
38
  }
23
39
 
40
+ type ExpoGlobalType = {
41
+ modules: {
42
+ ExpoAsset: ExpoAssetModule;
43
+ ExpoFontLoader: ExpoFontLoaderModule;
44
+ };
45
+ };
46
+
47
+ // biome-ignore lint/suspicious/noExplicitAny: this is used internally with globalThis
48
+ function getIsDynamicLoadingSupported(globalObj: any): globalObj is {
49
+ expo: ExpoGlobalType;
50
+ } {
51
+ return (
52
+ globalObj?.expo &&
53
+ typeof globalObj.expo.modules?.ExpoAsset?.downloadAsync === 'function' &&
54
+ typeof globalObj.expo.modules?.ExpoFontLoader?.getLoadedFonts === 'function' &&
55
+ typeof globalObj.expo.modules?.ExpoFontLoader?.loadAsync === 'function'
56
+ );
57
+ }
58
+
59
+ // biome-ignore lint/suspicious/noExplicitAny: this is used internally with globalThis
60
+ export function getIsRenderToImageSupported(globalObj: any): globalObj is {
61
+ expo: {
62
+ modules: {
63
+ ExpoFontUtils: ExpoFontUtilsModule;
64
+ };
65
+ };
66
+ } {
67
+ return globalObj?.expo && typeof globalObj.expo.modules?.ExpoFontUtils?.renderToImageAsync === 'function';
68
+ }
69
+
70
+ export function assertExpoModulesPresent(globalObj: unknown): asserts globalObj is { expo: ExpoGlobalType } {
71
+ if (!getIsDynamicLoadingSupported(globalObj)) {
72
+ throw new Error('Dynamic font loading for Expo is not available.');
73
+ }
74
+ }
75
+
24
76
  const hasNecessaryExpoModules = !!globalThis.expo?.modules?.ExpoAsset && !!globalThis.expo?.modules?.ExpoFontLoader;
25
77
 
26
- const hasNecessaryExpoFeatures =
27
- hasNecessaryExpoModules && typeof globalThis.expo?.modules.ExpoFontLoader.getLoadedFonts === 'function';
78
+ const hasNecessaryExpoFeatures = getIsDynamicLoadingSupported(globalThis);
28
79
 
29
80
  let dynamicFontLoadingEnabled = hasNecessaryExpoFeatures;
30
81
 
@@ -59,11 +110,7 @@ export const setDynamicLoadingEnabled = (value: boolean): boolean => {
59
110
  * */
60
111
  export const isDynamicLoadingEnabled = () => dynamicFontLoadingEnabled;
61
112
 
62
- type ErrorCallback = (args: {
63
- error: Error;
64
- fontFamily: string;
65
- fontSource: FontSource;
66
- }) => void;
113
+ type ErrorCallback = (args: { error: Error; fontFamily: string; fontSource: FontSource }) => void;
67
114
 
68
115
  let dynamicLoadingErrorCallback: undefined | ErrorCallback;
69
116
 
@@ -1,3 +1,5 @@
1
+ import { getIsRenderToImageSupported } from './dynamicLoading/dynamic-loading-setting';
2
+
1
3
  // eslint-disable-next-line import/no-mutable-exports
2
4
  let NativeIconAPI: typeof import('@react-native-vector-icons/get-image') | null = null;
3
5
 
@@ -5,17 +7,36 @@ try {
5
7
  // eslint-disable-next-line global-require,import/no-extraneous-dependencies,@typescript-eslint/no-require-imports
6
8
  NativeIconAPI = require('@react-native-vector-icons/get-image');
7
9
  } catch {
8
- // No warning at this stage
10
+ // if this fails, it's likely due to:
11
+ // "Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'VectorIcons' could not be found. ..."
12
+ // No warning at this stage.
9
13
  }
10
14
 
15
+ const globalRef = globalThis;
16
+ const hasExpoRenderToImage = getIsRenderToImageSupported(globalRef);
17
+
11
18
  export const ensureGetImageAvailable = () => {
12
- if (!NativeIconAPI) {
13
- throw new Error(
14
- 'Could not import @react-native-vector-icons/get-image, did you install it? It is required for getImageSource*',
15
- );
19
+ if (NativeIconAPI) {
20
+ NativeIconAPI.ensureNativeModuleAvailable();
21
+ return NativeIconAPI;
16
22
  }
17
-
18
- NativeIconAPI.ensureNativeModuleAvailable();
19
-
20
- return NativeIconAPI;
23
+ if (hasExpoRenderToImage) {
24
+ const { ExpoFontUtils } = globalRef.expo.modules;
25
+ return {
26
+ getImageForFont: async (fontReference: string, glyph: string, size: number, color: number) =>
27
+ ExpoFontUtils.renderToImageAsync(glyph, {
28
+ fontFamily: fontReference,
29
+ size,
30
+ color,
31
+ }),
32
+ getImageForFontSync: () => {
33
+ throw new Error(
34
+ 'You attempted to call `getImageForFontSync`. Expo dev client with `@react-native-vector-icons/get-image` installed is required for this. Alternatively, call `getImageForFont` or generate the image yourself and bundle it with the app.',
35
+ );
36
+ },
37
+ };
38
+ }
39
+ throw new Error(
40
+ 'Error in getImageSource / getImageSourceSync: You need to either (1) install `@react-native-vector-icons/get-image` or (2) use Expo SDK 53+ (Expo dev client or Expo Go). Check your setup and rebuild the app.',
41
+ );
21
42
  };
@@ -0,0 +1,74 @@
1
+ import type { TextStyle } from 'react-native';
2
+ import { PixelRatio, processColor } from 'react-native';
3
+
4
+ import type createIconSourceCache from './create-icon-source-cache';
5
+ import { DEFAULT_ICON_COLOR, DEFAULT_ICON_SIZE } from './defaults';
6
+ import { ensureGetImageAvailable } from './get-image-library';
7
+
8
+ export const getImageSourceSync = (
9
+ imageSourceCache: ReturnType<typeof createIconSourceCache>,
10
+ fontReference: string,
11
+ glyph: string,
12
+ size = DEFAULT_ICON_SIZE,
13
+ color: TextStyle['color'] = DEFAULT_ICON_COLOR,
14
+ ) => {
15
+ const NativeIconAPI = ensureGetImageAvailable();
16
+
17
+ const processedColor = processColor(color);
18
+ const cacheKey = `${glyph}:${size}:${String(processedColor)}`;
19
+
20
+ const maybeCachedValue = imageSourceCache.get(cacheKey);
21
+ if (maybeCachedValue !== undefined) {
22
+ // FIXME: Should this check if it's an error and throw it again?
23
+ return maybeCachedValue;
24
+ }
25
+
26
+ try {
27
+ const imagePath = NativeIconAPI.getImageForFontSync(
28
+ fontReference,
29
+ glyph,
30
+ size,
31
+ processedColor as number, // FIXME what if a non existent colour was passed in?
32
+ );
33
+ const value = { uri: imagePath, scale: PixelRatio.get() };
34
+ imageSourceCache.setValue(cacheKey, value);
35
+ return value;
36
+ } catch (error) {
37
+ imageSourceCache.setError(cacheKey, error as Error);
38
+ throw error;
39
+ }
40
+ };
41
+
42
+ export const getImageSource = async (
43
+ imageSourceCache: ReturnType<typeof createIconSourceCache>,
44
+ fontReference: string,
45
+ glyph: string,
46
+ size = DEFAULT_ICON_SIZE,
47
+ color: TextStyle['color'] = DEFAULT_ICON_COLOR,
48
+ ) => {
49
+ const NativeIconAPI = ensureGetImageAvailable();
50
+
51
+ const processedColor = processColor(color);
52
+ const cacheKey = `${glyph}:${size}:${String(processedColor)}`;
53
+
54
+ const maybeCachedValue = imageSourceCache.get(cacheKey);
55
+ if (maybeCachedValue !== undefined) {
56
+ // FIXME: Should this check if it's an error and throw it again?
57
+ return maybeCachedValue;
58
+ }
59
+
60
+ try {
61
+ const imagePath = await NativeIconAPI.getImageForFont(
62
+ fontReference,
63
+ glyph,
64
+ size,
65
+ processedColor as number, // FIXME what if a non existent colour was passed in?
66
+ );
67
+ const value = { uri: imagePath, scale: PixelRatio.get() };
68
+ imageSourceCache.setValue(cacheKey, value);
69
+ return value;
70
+ } catch (error) {
71
+ imageSourceCache.setError(cacheKey, error as Error);
72
+ throw error;
73
+ }
74
+ };
package/src/index.ts CHANGED
@@ -1,8 +1,9 @@
1
- export { createIconSet, DEFAULT_ICON_SIZE, DEFAULT_ICON_COLOR } from './create-icon-set';
2
- export type { IconProps, CreateIconSetOptions } from './create-icon-set';
1
+ export type { CreateIconSetOptions, IconProps } from './create-icon-set';
2
+ export { createIconSet } from './create-icon-set';
3
+ export { DEFAULT_ICON_COLOR, DEFAULT_ICON_SIZE } from './defaults';
3
4
  export {
4
- setDynamicLoadingEnabled,
5
5
  isDynamicLoadingEnabled,
6
6
  isDynamicLoadingSupported,
7
+ setDynamicLoadingEnabled,
7
8
  setDynamicLoadingErrorCallback,
8
9
  } from './dynamicLoading/dynamic-loading-setting';
@@ -1,5 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
+
3
4
  import { resolveNodeModuleDir } from '@react-native-community/cli-tools';
4
5
 
5
6
  const getPackageJson = (filename: string) => {
@@ -3,6 +3,7 @@
3
3
 
4
4
  import fs from 'node:fs';
5
5
  import * as path from 'node:path';
6
+
6
7
  import pc from 'picocolors';
7
8
  import * as plist from 'plist';
8
9