@admin-layout/gluestack-ui-mobile 9.0.4-alpha.28 → 9.0.4-alpha.39

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/CHANGELOG.md +8 -0
  2. package/lib/components/AuthWrapper.d.ts +4 -2
  3. package/lib/components/AuthWrapper.js +5 -5
  4. package/lib/components/AuthWrapper.js.map +1 -1
  5. package/lib/components/WithConfiguration.d.ts +18 -0
  6. package/lib/components/WithConfiguration.js +41 -0
  7. package/lib/components/WithConfiguration.js.map +1 -0
  8. package/lib/components/WithPermission.d.ts +31 -0
  9. package/lib/components/WithPermission.js +56 -0
  10. package/lib/components/WithPermission.js.map +1 -0
  11. package/lib/components/WithPolicy.d.ts +13 -0
  12. package/lib/components/WithPolicy.js +18 -0
  13. package/lib/components/WithPolicy.js.map +1 -0
  14. package/lib/components/index.d.ts +5 -0
  15. package/lib/components/index.js +5 -0
  16. package/lib/components/index.js.map +1 -1
  17. package/lib/components/usePermissionAutoFetch.d.ts +63 -0
  18. package/lib/components/usePermissionAutoFetch.js +23 -0
  19. package/lib/components/usePermissionAutoFetch.js.map +1 -0
  20. package/lib/components/useSetting.d.ts +25 -0
  21. package/lib/components/useSetting.js +93 -0
  22. package/lib/components/useSetting.js.map +1 -0
  23. package/lib/components/with-interactions-lifecycle-managed.d.ts +3 -3
  24. package/lib/components/with-interactions-lifecycle-managed.js +19 -9
  25. package/lib/components/with-interactions-lifecycle-managed.js.map +1 -1
  26. package/lib/utils/generateMobileNavigations.js +150 -13
  27. package/lib/utils/generateMobileNavigations.js.map +1 -1
  28. package/package.json +3 -3
  29. package/src/components/AuthWrapper.tsx +5 -4
  30. package/src/components/WithConfiguration.tsx +73 -0
  31. package/src/components/WithPermission.tsx +85 -0
  32. package/src/components/WithPolicy.tsx +32 -0
  33. package/src/components/index.ts +6 -1
  34. package/src/components/usePermissionAutoFetch.tsx +27 -0
  35. package/src/components/useSetting.tsx +144 -0
  36. package/src/components/with-interactions-lifecycle-managed.tsx +56 -14
  37. package/src/utils/generateMobileNavigations.ts +175 -20
@@ -76,13 +76,15 @@ export class GenerateMobileNavigations {
76
76
  #customDrawerPath: string;
77
77
  #customHeaderPath: string;
78
78
  #i18Options: any;
79
+ #iconsRepository: string;
79
80
 
80
81
  constructor({ configFilePath }: IGenerateMobileNavigationsProps) {
81
82
  this.#configFilePath = configFilePath;
82
83
  const config = this.#readConfigFile(configFilePath);
83
84
  this.#configFileData = config;
84
85
  // this.#layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
85
- this.#appPath = config?.appPath ?? 'app';
86
+ this.#appPath = config?.commonPaths?.appPath ?? 'app';
87
+ this.#iconsRepository = config?.iconsRepository ?? '';
86
88
  this.#mobileStackPath = config?.mobileStackPath ?? 'mobile-stack-react';
87
89
  this.#appDirPath = path.join(path.dirname(configFilePath), this.#appPath);
88
90
  this.#modules = config?.modules ?? [];
@@ -706,6 +708,7 @@ export class GenerateMobileNavigations {
706
708
  }}}}
707
709
  >{(props) => <AuthWrapper
708
710
  auth={${pkgRouteConfig?.props?.initialParams?.auth ?? false}}
711
+ authority={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
709
712
  component={<Component${moduleNumber} {...props} />}
710
713
  ${
711
714
  pkgRouteConfig?.unauthenticatedComponent && customUnauthenticatedComponentPath
@@ -788,6 +791,7 @@ export class GenerateMobileNavigations {
788
791
 
789
792
  importStatements += `import * as React from 'react';\n`;
790
793
  importStatements += `import AuthWrapper from '@admin-layout/gluestack-ui-mobile/lib/components/AuthWrapper.js';\n`;
794
+ importStatements += `import DynamicIcons from '@app/selectiveIcons';\n`;
791
795
 
792
796
  if (unauthenticatedComponentPath)
793
797
  importStatements += `import UnauthenticatedComponent from '${unauthenticatedComponentPath}';\n`;
@@ -833,11 +837,35 @@ export class GenerateMobileNavigations {
833
837
  initialParams={${JSON.stringify(pkgRouteConfig?.props?.initialParams || {})}}
834
838
  options={{...${options},...{${
835
839
  pkgRouteConfig?.icon && Object.keys(pkgRouteConfig.icon)?.length && pkgRouteConfig?.icon?.name
836
- ? `drawerIcon: ({ color, size }) => <${pkgRouteConfig?.icon?.name} name="${
837
- pkgRouteConfig?.icon?.props?.name ?? 'home'
838
- }" size={${pkgRouteConfig?.icon?.props?.size ?? `size`}} color={${
839
- pkgRouteConfig?.icon?.props?.color ?? 'color'
840
- }} />,`
840
+ ? `drawerIcon: ({ focused }) => {
841
+ const SelectedIcon = DynamicIcons('${pkgRouteConfig?.icon?.name}');
842
+ return (<SelectedIcon
843
+ {...{
844
+ ...${JSON.stringify({ ...(pkgRouteConfig?.icon?.props || {}) })},
845
+ ...{
846
+ color:focused ? ${
847
+ JSON.stringify(
848
+ pkgRouteConfig?.icon?.props?.color ??
849
+ pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
850
+ ) ?? 'black'
851
+ }
852
+ :${
853
+ JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
854
+ 'grey'
855
+ },
856
+ stroke:focused ? ${
857
+ JSON.stringify(
858
+ pkgRouteConfig?.icon?.props?.color ??
859
+ pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
860
+ ) ?? 'black'
861
+ }
862
+ :${
863
+ JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
864
+ 'grey'
865
+ }
866
+ }
867
+ }}
868
+ />)},`
841
869
  : ''
842
870
  }
843
871
  ${
@@ -851,6 +879,7 @@ export class GenerateMobileNavigations {
851
879
  }}}}
852
880
  >{(props) => <AuthWrapper
853
881
  auth={${pkgRouteConfig?.props?.initialParams?.auth ?? false}}
882
+ authority={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
854
883
  component={<Component${moduleNumber} {...props} />}
855
884
  ${
856
885
  pkgRouteConfig?.unauthenticatedComponent && customUnauthenticatedComponentPath
@@ -878,10 +907,10 @@ export class GenerateMobileNavigations {
878
907
  }
879
908
  />}</Drawer.Screen>`;
880
909
  }
881
- if (icons && icons?.length) {
882
- const uniqueIcons = [...new Set(icons.split(','))].join(',');
883
- importStatements += `import { ${uniqueIcons} } from '@expo/vector-icons';\n`;
884
- }
910
+ // if (icons && icons?.length) {
911
+ // const uniqueIcons = [...new Set(icons.split(','))].join(',');
912
+ // importStatements += `import Icons from '@expo/vector-icons';\n`;
913
+ // }
885
914
 
886
915
  if (customHeaderPaths && customHeaderPaths?.length) {
887
916
  const uniqueHeaderNames = [...new Set(customHeaderNames.split(','))]?.filter((str) => str?.length);
@@ -1014,6 +1043,7 @@ export class GenerateMobileNavigations {
1014
1043
 
1015
1044
  importStatements += `import * as React from 'react';\n`;
1016
1045
  importStatements += `import AuthWrapper from '@admin-layout/gluestack-ui-mobile/lib/components/AuthWrapper.js';\n`;
1046
+ importStatements += `import DynamicIcons from '@app/selectiveIcons';\n`;
1017
1047
 
1018
1048
  if (unauthenticatedComponentPath)
1019
1049
  importStatements += `import UnauthenticatedComponent from '${unauthenticatedComponentPath}';\n`;
@@ -1060,7 +1090,6 @@ export class GenerateMobileNavigations {
1060
1090
  }
1061
1091
  : { headerShown: mixLayout ? false : true },
1062
1092
  );
1063
-
1064
1093
  importStatements += `import Component${moduleNumber} from '${pkgRouteConfig.componentPath}';\n`;
1065
1094
  moduleContent += `<Tab.Screen
1066
1095
  key="${pkgRouteConfig.key}"
@@ -1069,11 +1098,36 @@ export class GenerateMobileNavigations {
1069
1098
  initialParams={${JSON.stringify(pkgRouteConfig?.props?.initialParams || {})}}
1070
1099
  options={{...${options},...{${
1071
1100
  pkgRouteConfig?.icon && Object.keys(pkgRouteConfig.icon)?.length && pkgRouteConfig?.icon?.name
1072
- ? `tabBarIcon: ({ color }) => <${pkgRouteConfig?.icon?.name} name="${
1073
- pkgRouteConfig?.icon?.props?.name ?? 'home'
1074
- }" size={${pkgRouteConfig?.icon?.props?.size ?? 24}} color={${
1075
- pkgRouteConfig?.icon?.props?.color ?? 'color'
1076
- }} />`
1101
+ ? `tabBarIcon: ({ focused }) => {
1102
+ const SelectedIcon = DynamicIcons('${pkgRouteConfig?.icon?.name}');
1103
+ return (<SelectedIcon
1104
+ {...{
1105
+ ...${JSON.stringify({ ...(pkgRouteConfig?.icon?.props || {}) })},
1106
+ ...{
1107
+ color:focused ? ${
1108
+ JSON.stringify(
1109
+ pkgRouteConfig?.icon?.props?.color ??
1110
+ pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
1111
+ ) ?? 'black'
1112
+ }
1113
+ :${
1114
+ JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
1115
+ 'grey'
1116
+ },
1117
+ stroke:focused ? ${
1118
+ JSON.stringify(
1119
+ pkgRouteConfig?.icon?.props?.color ??
1120
+ pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
1121
+ ) ?? 'black'
1122
+ }
1123
+ :${
1124
+ JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
1125
+ 'grey'
1126
+ }
1127
+ }
1128
+ }}
1129
+
1130
+ />)}`
1077
1131
  : ''
1078
1132
  }
1079
1133
  ${
@@ -1088,6 +1142,7 @@ export class GenerateMobileNavigations {
1088
1142
  }}}
1089
1143
  >{(props) => <AuthWrapper
1090
1144
  auth={${pkgRouteConfig?.props?.initialParams?.auth ?? false}}
1145
+ authority={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
1091
1146
  component={<Component${moduleNumber} {...props} />}
1092
1147
  ${
1093
1148
  pkgRouteConfig?.unauthenticatedComponent && customUnauthenticatedComponentPath
@@ -1117,10 +1172,10 @@ export class GenerateMobileNavigations {
1117
1172
  </Tab.Screen>`;
1118
1173
  }
1119
1174
 
1120
- if (icons && icons?.length) {
1121
- const uniqueIcons = [...new Set(icons.split(','))].join(',');
1122
- importStatements += `import { ${uniqueIcons} } from '@expo/vector-icons';\n`;
1123
- }
1175
+ // if (icons && icons?.length) {
1176
+ // const uniqueIcons = [...new Set(icons.split(','))].join(',');
1177
+ // importStatements += `import { ${uniqueIcons} } from '@expo/vector-icons';\n`;
1178
+ // }
1124
1179
 
1125
1180
  if (customHeaderPaths && customHeaderPaths?.length) {
1126
1181
  const uniqueHeaderNames = [...new Set(customHeaderNames.split(','))]?.filter((str) => str?.length);
@@ -1577,6 +1632,105 @@ export class GenerateMobileNavigations {
1577
1632
  }
1578
1633
  }
1579
1634
 
1635
+ async #generateSelectiveIconsFile({ appDirPath, modules }) {
1636
+ const mainRoutes = path.join(appDirPath, `/${mainRoutesFileName}`);
1637
+ const modulesRouteConfig = await this.#getModulesRouteConfig({ modules: modules });
1638
+ const mainRouteConfig = await this.#readJsonFile(mainRoutes);
1639
+ const allRoutes = [...[mainRouteConfig ?? []], ...(modulesRouteConfig ?? [])];
1640
+ let iconNames = [];
1641
+ allRoutes?.flat(1)?.forEach((route) => {
1642
+ const key = Object.keys(route)[0];
1643
+ const value = route[key];
1644
+ if (value?.icon && typeof value.icon === 'object') {
1645
+ if (typeof value.icon.name === 'string') {
1646
+ if (!iconNames.includes(value.icon.name)) iconNames.push(value.icon.name);
1647
+ }
1648
+ } else if (value?.icon && typeof value.icon === 'string') {
1649
+ if (!iconNames.includes(value.icon)) iconNames.push(value.icon);
1650
+ }
1651
+
1652
+ if (value?.extraIcons && Array.isArray(value.extraIcons) && value?.extraIcons?.length > 0) {
1653
+ value?.extraIcons?.map((icon) => {
1654
+ if (typeof icon === 'string') {
1655
+ if (!iconNames.includes(icon)) iconNames.push(icon);
1656
+ } else {
1657
+ console.warn(`Invalid icon type: ${typeof icon}`);
1658
+ }
1659
+ });
1660
+ } else if (value?.extraIcons && typeof value.extraIcons === 'string') {
1661
+ if (!iconNames.includes(value.extraIcons)) iconNames.push(value.extraIcons);
1662
+ }
1663
+ });
1664
+
1665
+ const iconsRepository = this.#iconsRepository;
1666
+ const expoIcons = [
1667
+ 'AntDesign',
1668
+ 'Entypo',
1669
+ 'EvilIcons',
1670
+ 'Feather',
1671
+ 'FontAwesome',
1672
+ 'FontAwesome5',
1673
+ 'Fontisto',
1674
+ 'Foundation',
1675
+ 'Ionicons',
1676
+ 'MaterialCommunityIcons',
1677
+ 'MaterialIcons',
1678
+ 'Octicons',
1679
+ 'SimpleLineIcons',
1680
+ 'Zocial',
1681
+ ];
1682
+
1683
+ let content = `
1684
+ function __variableDynamicIcon(icon) {
1685
+ switch (icon) {
1686
+ `;
1687
+ iconNames.forEach((name) => {
1688
+ let prefix, iconName;
1689
+ if (name.includes('.')) {
1690
+ [prefix, iconName] = name.split('.');
1691
+ }
1692
+ if (prefix && iconsRepository[prefix]) {
1693
+ const importPath = iconsRepository[prefix].replace(
1694
+ '{iconName}',
1695
+ prefix === 'expo' ? iconName : iconName + '.native',
1696
+ );
1697
+ // prefix = prefix.charAt(0).toUpperCase() + prefix.slice(1).toLowerCase();
1698
+ content += `
1699
+ case '${prefix + '.' + iconName}':
1700
+ return require('${importPath}')?.default;
1701
+ `;
1702
+ } else {
1703
+ content += `
1704
+ case '${name}':
1705
+ return ${
1706
+ expoIcons.includes(name)
1707
+ ? `require('@expo/vector-icons/${name}.js')?.default`
1708
+ : `require('@expo/vector-icons/FontAwesome.js')?.default;`
1709
+ };
1710
+ `;
1711
+ }
1712
+ });
1713
+
1714
+ content += `
1715
+ default:
1716
+ console.warn('Sorry, the icon named "', icon, '" could not be found in "@react-icon/all-files" and "@app/icons". Please check again.');
1717
+ return require('@expo/vector-icons/FontAwesome.js')?.default;
1718
+ }
1719
+ }
1720
+ export default function(icon) {
1721
+ return __variableDynamicIcon(icon);
1722
+ }
1723
+ `;
1724
+ const rootPath = process.cwd();
1725
+ const fileName = `selectiveIcons.js`;
1726
+ const newFilePath = path.join(rootPath, 'app', fileName);
1727
+ // Ensure the directory exists
1728
+ if (!fs.existsSync(path.dirname(newFilePath))) {
1729
+ fs.mkdirSync(path.dirname(newFilePath), { recursive: true });
1730
+ }
1731
+ fs.writeFileSync(newFilePath, content, 'utf8');
1732
+ }
1733
+
1580
1734
  async #setLayoutAndGenerateNavigation() {
1581
1735
  const appDirPath = this.#appDirPath;
1582
1736
  const modules = this.#modules;
@@ -1592,6 +1746,7 @@ export class GenerateMobileNavigations {
1592
1746
  const layoutType = layoutSettings?.layout || 'bottom';
1593
1747
  try {
1594
1748
  await this.#generateAppRoutesJson();
1749
+ await this.#generateSelectiveIconsFile({ appDirPath, modules });
1595
1750
  await this.#generateMainRoutes({
1596
1751
  appDirPath,
1597
1752
  i18Options,