@ankhorage/surface 1.0.2 → 1.0.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @ankhorage/surface
2
2
 
3
+ ## 1.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - c8c99de: Support canonical icon provider aliases for Expo vector icons.
8
+
9
+ Surface now resolves provider strings such as `material-community` and `material-community-icons` to Expo's `MaterialCommunityIcons` export, so serialized route icons can use stable provider identifiers without falling back to Ionicons.
10
+
3
11
  ## 1.0.2
4
12
 
5
13
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"resolveExpoIconComponent.d.ts","sourceRoot":"","sources":["../../../src/primitives/icon/resolveExpoIconComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9D,MAAM,MAAM,iBAAiB,GAAG,KAAK,CAAC,WAAW,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAEH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAO5E"}
1
+ {"version":3,"file":"resolveExpoIconComponent.d.ts","sourceRoot":"","sources":["../../../src/primitives/icon/resolveExpoIconComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9D,MAAM,MAAM,iBAAiB,GAAG,KAAK,CAAC,WAAW,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAMH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAQ5E"}
@@ -1,10 +1,20 @@
1
1
  import * as ExpoIcons from '@expo/vector-icons';
2
2
  import {} from 'react-native';
3
+ const EXPO_ICON_PROVIDER_ALIASES = {
4
+ 'material-community': 'MaterialCommunityIcons',
5
+ };
3
6
  export function resolveExpoIconComponent(provider) {
4
- const candidate = ExpoIcons[provider];
7
+ const normalizedProvider = resolveExpoIconProviderName(provider);
8
+ const candidate = ExpoIcons[normalizedProvider];
5
9
  if (typeof candidate === 'function') {
6
10
  return candidate;
7
11
  }
8
12
  return ExpoIcons.Ionicons;
9
13
  }
14
+ function resolveExpoIconProviderName(provider) {
15
+ const normalizedProvider = provider.trim().toLowerCase();
16
+ return normalizedProvider in EXPO_ICON_PROVIDER_ALIASES
17
+ ? EXPO_ICON_PROVIDER_ALIASES[normalizedProvider]
18
+ : provider;
19
+ }
10
20
  //# sourceMappingURL=resolveExpoIconComponent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolveExpoIconComponent.js","sourceRoot":"","sources":["../../../src/primitives/icon/resolveExpoIconComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAkC,MAAM,cAAc,CAAC;AAU9D,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACvD,MAAM,SAAS,GAAI,SAAqC,CAAC,QAAQ,CAAC,CAAC;IACnE,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,OAAO,SAA8B,CAAC;IACxC,CAAC;IAED,OAAO,SAAS,CAAC,QAA6B,CAAC;AACjD,CAAC","sourcesContent":["import * as ExpoIcons from '@expo/vector-icons';\nimport type React from 'react';\nimport { type StyleProp, type TextStyle } from 'react-native';\n\nexport type ExpoIconComponent = React.ElementType<{\n color?: string;\n name?: string;\n size?: number;\n style?: StyleProp<TextStyle>;\n testID?: string;\n}>;\n\nexport function resolveExpoIconComponent(provider: string): ExpoIconComponent {\n const candidate = (ExpoIcons as Record<string, unknown>)[provider];\n if (typeof candidate === 'function') {\n return candidate as ExpoIconComponent;\n }\n\n return ExpoIcons.Ionicons as ExpoIconComponent;\n}\n"]}
1
+ {"version":3,"file":"resolveExpoIconComponent.js","sourceRoot":"","sources":["../../../src/primitives/icon/resolveExpoIconComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAkC,MAAM,cAAc,CAAC;AAU9D,MAAM,0BAA0B,GAAG;IACjC,oBAAoB,EAAE,wBAAwB;CACtC,CAAC;AAEX,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACvD,MAAM,kBAAkB,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IACjE,MAAM,SAAS,GAAI,SAAqC,CAAC,kBAAkB,CAAC,CAAC;IAC7E,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,OAAO,SAA8B,CAAC;IACxC,CAAC;IAED,OAAO,SAAS,CAAC,QAA6B,CAAC;AACjD,CAAC;AAED,SAAS,2BAA2B,CAAC,QAAgB;IACnD,MAAM,kBAAkB,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAEzD,OAAO,kBAAkB,IAAI,0BAA0B;QACrD,CAAC,CAAC,0BAA0B,CAAC,kBAA6D,CAAC;QAC3F,CAAC,CAAC,QAAQ,CAAC;AACf,CAAC","sourcesContent":["import * as ExpoIcons from '@expo/vector-icons';\nimport type React from 'react';\nimport { type StyleProp, type TextStyle } from 'react-native';\n\nexport type ExpoIconComponent = React.ElementType<{\n color?: string;\n name?: string;\n size?: number;\n style?: StyleProp<TextStyle>;\n testID?: string;\n}>;\n\nconst EXPO_ICON_PROVIDER_ALIASES = {\n 'material-community': 'MaterialCommunityIcons',\n} as const;\n\nexport function resolveExpoIconComponent(provider: string): ExpoIconComponent {\n const normalizedProvider = resolveExpoIconProviderName(provider);\n const candidate = (ExpoIcons as Record<string, unknown>)[normalizedProvider];\n if (typeof candidate === 'function') {\n return candidate as ExpoIconComponent;\n }\n\n return ExpoIcons.Ionicons as ExpoIconComponent;\n}\n\nfunction resolveExpoIconProviderName(provider: string): string {\n const normalizedProvider = provider.trim().toLowerCase();\n\n return normalizedProvider in EXPO_ICON_PROVIDER_ALIASES\n ? EXPO_ICON_PROVIDER_ALIASES[normalizedProvider as keyof typeof EXPO_ICON_PROVIDER_ALIASES]\n : provider;\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/surface",
3
3
  "type": "module",
4
- "version": "1.0.2",
4
+ "version": "1.0.3",
5
5
  "description": "Stable UI foundation for React Native and React Native Web.",
6
6
  "homepage": "https://github.com/ankhorage/surface#readme",
7
7
  "bugs": {
@@ -2,11 +2,13 @@ import { describe, expect, mock, test } from 'bun:test';
2
2
 
3
3
  const Ionicons = () => null;
4
4
  const MaterialIcons = () => null;
5
+ const MaterialCommunityIcons = () => null;
5
6
 
6
7
  describe('resolveExpoIconComponent', () => {
7
8
  test('returns the requested Expo icon family when it exists', async () => {
8
9
  await mock.module('@expo/vector-icons', () => ({
9
10
  Ionicons,
11
+ MaterialCommunityIcons,
10
12
  MaterialIcons,
11
13
  }));
12
14
 
@@ -14,11 +16,25 @@ describe('resolveExpoIconComponent', () => {
14
16
 
15
17
  expect(resolveExpoIconComponent('Ionicons')).toBe(Ionicons);
16
18
  expect(resolveExpoIconComponent('MaterialIcons')).toBe(MaterialIcons);
19
+ expect(resolveExpoIconComponent('MaterialCommunityIcons')).toBe(MaterialCommunityIcons);
20
+ });
21
+
22
+ test('resolves the canonical material-community provider id', async () => {
23
+ await mock.module('@expo/vector-icons', () => ({
24
+ Ionicons,
25
+ MaterialCommunityIcons,
26
+ MaterialIcons,
27
+ }));
28
+
29
+ const { resolveExpoIconComponent } = await import('./resolveExpoIconComponent');
30
+
31
+ expect(resolveExpoIconComponent('material-community')).toBe(MaterialCommunityIcons);
17
32
  });
18
33
 
19
34
  test('falls back to Ionicons when the provider is unknown', async () => {
20
35
  await mock.module('@expo/vector-icons', () => ({
21
36
  Ionicons,
37
+ MaterialCommunityIcons,
22
38
  MaterialIcons,
23
39
  }));
24
40
 
@@ -10,11 +10,24 @@ export type ExpoIconComponent = React.ElementType<{
10
10
  testID?: string;
11
11
  }>;
12
12
 
13
+ const EXPO_ICON_PROVIDER_ALIASES = {
14
+ 'material-community': 'MaterialCommunityIcons',
15
+ } as const;
16
+
13
17
  export function resolveExpoIconComponent(provider: string): ExpoIconComponent {
14
- const candidate = (ExpoIcons as Record<string, unknown>)[provider];
18
+ const normalizedProvider = resolveExpoIconProviderName(provider);
19
+ const candidate = (ExpoIcons as Record<string, unknown>)[normalizedProvider];
15
20
  if (typeof candidate === 'function') {
16
21
  return candidate as ExpoIconComponent;
17
22
  }
18
23
 
19
24
  return ExpoIcons.Ionicons as ExpoIconComponent;
20
25
  }
26
+
27
+ function resolveExpoIconProviderName(provider: string): string {
28
+ const normalizedProvider = provider.trim().toLowerCase();
29
+
30
+ return normalizedProvider in EXPO_ICON_PROVIDER_ALIASES
31
+ ? EXPO_ICON_PROVIDER_ALIASES[normalizedProvider as keyof typeof EXPO_ICON_PROVIDER_ALIASES]
32
+ : provider;
33
+ }