diff --git a/Example/App.js b/Example/App.js index ad92f09..051d8e7 100644 --- a/Example/App.js +++ b/Example/App.js @@ -46,7 +46,7 @@ export default class App extends Component<{}> { }, { label: "Paste", - icon: paste + icon: 'paste.png' }, { label: "Share", @@ -68,7 +68,7 @@ export default class App extends Component<{}> { }, { label: "Paste", - icon: paste + icon: 'paste.png' } ] }, diff --git a/Example/android/app/src/main/res/drawable/paste.png b/Example/android/app/src/main/res/drawable/paste.png new file mode 100644 index 0000000..14b7951 Binary files /dev/null and b/Example/android/app/src/main/res/drawable/paste.png differ diff --git a/Example/android/build.gradle b/Example/android/build.gradle index 304b7c7..221c97e 100644 --- a/Example/android/build.gradle +++ b/Example/android/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:3.1.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/Example/android/gradle/wrapper/gradle-wrapper.properties b/Example/android/gradle/wrapper/gradle-wrapper.properties index 5daed74..343e5f0 100644 --- a/Example/android/gradle/wrapper/gradle-wrapper.properties +++ b/Example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Jan 31 15:54:01 IST 2018 +#Sun May 27 20:51:31 IST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/Example/ios/Example.xcodeproj/project.pbxproj b/Example/ios/Example.xcodeproj/project.pbxproj index 64edb89..00b5078 100644 --- a/Example/ios/Example.xcodeproj/project.pbxproj +++ b/Example/ios/Example.xcodeproj/project.pbxproj @@ -48,6 +48,7 @@ 94C7128F4CA7445280B5314C /* MaterialIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C831003D7E6946C09035CBCC /* MaterialIcons.ttf */; }; ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */; }; B3866D926C8644C8B7BF9140 /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D7B7344D79414585A99B09B5 /* libRNVectorIcons.a */; }; + CEBCF54120BAFF0100E38EBD /* paste.png in Resources */ = {isa = PBXBuildFile; fileRef = CEBCF51920BAFF0100E38EBD /* paste.png */; }; E0BE039A6D494AA8B3E6A207 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2994E3C1FB86403B8403A09D /* Zocial.ttf */; }; F705588D6AB146B0AD6A66E2 /* EvilIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 534DB364FAC74C0A8E624F3B /* EvilIcons.ttf */; }; /* End PBXBuildFile section */ @@ -382,6 +383,7 @@ C67D645C7914439084DB2DBC /* FontAwesome.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome.ttf; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf"; sourceTree = ""; }; C831003D7E6946C09035CBCC /* MaterialIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf"; sourceTree = ""; }; CC17475F4B294B24B996F06D /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNVectorIcons.xcodeproj; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = ""; }; + CEBCF51920BAFF0100E38EBD /* paste.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = paste.png; sourceTree = ""; }; D78A30C33D594BCBA8385206 /* RNPopoverMenu.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNPopoverMenu.xcodeproj; path = "../node_modules/react-native-popover-menu/ios/RNPopoverMenu.xcodeproj"; sourceTree = ""; }; D7B7344D79414585A99B09B5 /* libRNVectorIcons.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNVectorIcons.a; sourceTree = ""; }; /* End PBXFileReference section */ @@ -644,6 +646,7 @@ 8D19D63E49FE46A898CAE16D /* Resources */ = { isa = PBXGroup; children = ( + CEBCF51920BAFF0100E38EBD /* paste.png */, 6C0D00F770BD4D33AC2620E5 /* Entypo.ttf */, 534DB364FAC74C0A8E624F3B /* EvilIcons.ttf */, 49269C25FA4F4C64B8444C03 /* Feather.ttf */, @@ -1160,6 +1163,7 @@ buildActionMask = 2147483647; files = ( 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, + CEBCF54120BAFF0100E38EBD /* paste.png in Resources */, 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 2C94D697F4AF44E58006F93D /* Entypo.ttf in Resources */, F705588D6AB146B0AD6A66E2 /* EvilIcons.ttf in Resources */, diff --git a/Example/ios/Example/paste.png b/Example/ios/Example/paste.png new file mode 100644 index 0000000..09a89c7 Binary files /dev/null and b/Example/ios/Example/paste.png differ diff --git a/README.md b/README.md index b2771ff..8b21b07 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,32 @@ RNPopoverMenu.Show(this.ref, { | `rowHeight` | `number` | | Height of the menu row | + +## Icons + +- **RN Vector Icons:** It supports [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons) library. Please find below snippet for the usage: + +```javascript + let facebook = + + +``` + +> **Note:** +> - We have added `family` prop for `Icon` class, please make sure that you pass the props + + +- **Custom Icons** + +> **Note:** +> Since we are using native libraries, we have not found a solution in order to render RN Images in production, therefore please copy all your image assets in platform specific folders: + +- Android: Please copy your image assets in app resource drawable folder +- iOS: Please copy your image assets in app resources folder + +> Please refer example application for the image usage. + + ## Credits - Android: [zawadz88/MaterialPopupMenu](https://github.com/zawadz88/MaterialPopupMenu) diff --git a/android/src/main/java/ui/popovermenu/RNPopoverMenuModule.java b/android/src/main/java/ui/popovermenu/RNPopoverMenuModule.java index f7a49ca..e8d15bd 100644 --- a/android/src/main/java/ui/popovermenu/RNPopoverMenuModule.java +++ b/android/src/main/java/ui/popovermenu/RNPopoverMenuModule.java @@ -4,6 +4,7 @@ import android.annotation.TargetApi; import android.app.Activity; import android.content.res.ColorStateList; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; @@ -175,6 +176,7 @@ public void run() { }); } + @TargetApi(21) private Drawable generateVectorIcon(ReadableMap icon) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); @@ -185,6 +187,14 @@ private Drawable generateVectorIcon(ReadableMap icon) { String color = icon.getString("color"); int size = icon.getInt("size"); + if (name != null && name.length() > 0 && name.contains(".")) { + Resources resources = getReactApplicationContext().getResources(); + name = name.substring(0, name.lastIndexOf(".")); + + final int resourceId = resources.getIdentifier(name, "drawable", getReactApplicationContext().getPackageName()); + return getReactApplicationContext().getDrawable(resourceId); + } + float scale = getReactApplicationContext().getResources().getDisplayMetrics().density; String scaleSuffix = "@" + (scale == (int) scale ? Integer.toString((int) scale) : Float.toString(scale)) + "x"; int fontSize = Math.round(size * scale); diff --git a/ios/RNPopoverMenu.m b/ios/RNPopoverMenu.m index 45b5cbb..528f2af 100644 --- a/ios/RNPopoverMenu.m +++ b/ios/RNPopoverMenu.m @@ -74,6 +74,10 @@ - (UIImage *) generateVectorIcon: (NSDictionary *) icon { NSNumber *size = [icon objectForKey: @"size"]; NSString *color = [icon objectForKey: @"color"]; + if (name != nil && [name length] > 0 && [name containsString: @"."]) { + return [UIImage imageNamed: name]; + } + UIColor *uiColor = [RNPopoverMenu colorFromHexCode: color]; CGFloat screenScale = RCTScreenScale(); diff --git a/js/Menu.js b/js/Menu.js index 2df8d00..f08b537 100644 --- a/js/Menu.js +++ b/js/Menu.js @@ -12,7 +12,7 @@ Menu.propTypes = { ...ViewPropTypes, label: PropTypes.string, - icon: PropTypes.number + icon: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }; Menu.defaultProps = { diff --git a/js/RNPopoverMenu.js b/js/RNPopoverMenu.js index ed57b69..69aef3c 100644 --- a/js/RNPopoverMenu.js +++ b/js/RNPopoverMenu.js @@ -49,23 +49,21 @@ class Popover extends PureComponent { subMenu.icon = subMenu.icon.props; let glyph = RNVectorHelper.Resolve(subMenu.icon.family, subMenu.icon.name); - subMenu.icon = Object.assign( - {}, - subMenu.icon, - { - glyph: glyph - } - ); + subMenu.icon = Object.assign({}, subMenu.icon, { + glyph: glyph + }); + } else if (subMenu.icon !== undefined) { + subMenu.icon = { name: subMenu.icon, family: "", glyph: "", color: "", size: 0 }; } }); if (menu.icon && menu.icon.props) { - menu.icon = menu.icon.props + menu.icon = menu.icon.props; let glyph = RNVectorHelper.Resolve(menu.icon.family, menu.icon.name); - menu.icon = Object.assign({}, menu.icon, { - glyph: glyph - }); + menu.icon = Object.assign({}, menu.icon, { glyph: glyph }); + } else if (menu.icon !== undefined) { + menu.icon = { name: menu.icon, family: "", glyph: "", color: "", size: 0 }; } }); diff --git a/package.json b/package.json index 33692b1..e818ed7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-native-popover-menu", - "version": "0.0.11", + "version": "0.0.12", "description": "React Native: Native Popover Menu", "main": "js/RNPopoverMenu.js", "scripts": {