inital commit

This commit is contained in:
chirag04 2015-05-18 23:07:42 -04:00
commit 23d9e912c8
14 changed files with 954 additions and 0 deletions

32
.flowconfig Normal file
View File

@ -0,0 +1,32 @@
[ignore]
# We fork some components by platform.
.*/*.web.js
.*/*.android.js
# Some modules have their own node_modules with overlap
.*/node_modules/node-haste/.*
# Ignore react-tools where there are overlaps, but don't ignore anything that
# react-native relies on
.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
.*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
.*/node_modules/react-tools/src/browser/ui/React.js
.*/node_modules/react-tools/src/core/ReactInstanceHandles.js
.*/node_modules/react-tools/src/event/EventPropagators.js
.*/node_modules/flux/lib/invariant.js
# Ignore jest
.*/node_modules/jest-cli/.*
# Ignore examples
.*/Examples/.*
[include]
[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
interfaces.js
[options]
module.system=haste

28
.gitignore vendored Normal file
View File

@ -0,0 +1,28 @@
# OSX
#
.DS_Store
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
# node.js
#
node_modules/
npm-debug.log

88
README.md Normal file
View File

@ -0,0 +1,88 @@
# react-native-tooltip
A react-native component from displaying tooltip. Uses UIMenuController.
### Add it to your project
1. Run `npm install react-native-tooltip --save`
2. Open your project in XCode, right click on `Libraries` and click `Add
Files to "Your Project Name"` [(Screenshot)](http://url.brentvatne.ca/jQp8) then [(Screenshot)](http://url.brentvatne.ca/1gqUD).
3. Add `libRNToolTip.a` to `Build Phases -> Link Binary With Libraries`
[(Screenshot)](http://url.brentvatne.ca/17Xfe).
4. Whenever you want to use it within React code now you can: `var ToolTipText = require('react-native-tooltip');`
## Example
```javascript
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
TouchableHighlight,
PixelRatio,
View,
} = React;
var ToolTipMenu = require('NativeModules').ToolTipMenu;
var ToolTipText = require('react-native-tooltip');
var tooltip = React.createClass({
getInitialState: function() {
return {
input: 'chirag',
}
},
handleChange: function(event) {
this.setState({input: event.nativeEvent.text});
},
handleFocus: function(change) {
ToolTipMenu.show(this.refs.input.getNodeHandle(), ['x', 'z']);
},
render: function() {
return (
<View style={styles.container}>
<View style={styles.textinputContainer}>
<ToolTipText
suppressHighlighting={true}
onChange={this.handleChange}
onPress={this.handleFocus}
ref={'input'}
style={styles.textinput}
>{this.state.input}</ToolTipText>
</View>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
textinputContainer: {
marginTop: 20,
justifyContent: 'center',
alignItems: 'center',
},
textinput: {
width: 60,
marginVertical: 2,
marginHorizontal: 2,
borderWidth: 1 / PixelRatio.get(),
borderRadius: 5,
borderColor: '#c7c7cc',
padding: 2,
fontSize: 14,
backgroundColor: 'white',
},
});
AppRegistry.registerComponent('tooltip', () => tooltip);
```
## Here is how it looks:
![Demo gif](https://github.com/chirag04/react-native-tooltip/blob/master/screenshot.png)

View File

@ -0,0 +1,403 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
4681C0251B05271A004D67D4 /* ToolTipMenu.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4681C0241B05271A004D67D4 /* ToolTipMenu.h */; };
4681C0271B05271A004D67D4 /* ToolTipMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 4681C0261B05271A004D67D4 /* ToolTipMenu.m */; };
4681C02D1B05271A004D67D4 /* libToolTipMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4681C0211B05271A004D67D4 /* libToolTipMenu.a */; };
469F58B71B069FF300C571E8 /* RCTToolTipText.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F58B61B069FF300C571E8 /* RCTToolTipText.m */; };
469F58B91B06A00C00C571E8 /* RCTToolTipTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 469F58B81B06A00C00C571E8 /* RCTToolTipTextManager.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
4681C02E1B05271A004D67D4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 4681C0191B05271A004D67D4 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4681C0201B05271A004D67D4;
remoteInfo = ToolTipMenu;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
4681C01F1B05271A004D67D4 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
4681C0251B05271A004D67D4 /* ToolTipMenu.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
4681C0211B05271A004D67D4 /* libToolTipMenu.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libToolTipMenu.a; sourceTree = BUILT_PRODUCTS_DIR; };
4681C0241B05271A004D67D4 /* ToolTipMenu.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ToolTipMenu.h; sourceTree = "<group>"; };
4681C0261B05271A004D67D4 /* ToolTipMenu.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ToolTipMenu.m; sourceTree = "<group>"; };
4681C02C1B05271A004D67D4 /* ToolTipMenuTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ToolTipMenuTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4681C0321B05271A004D67D4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
469F58B31B069F9800C571E8 /* RCTToolTipText.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTToolTipText.h; sourceTree = "<group>"; };
469F58B61B069FF300C571E8 /* RCTToolTipText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTToolTipText.m; sourceTree = "<group>"; };
469F58B81B06A00C00C571E8 /* RCTToolTipTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTToolTipTextManager.m; sourceTree = "<group>"; };
469F58BA1B06A01D00C571E8 /* RCTToolTipTextManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTToolTipTextManager.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
4681C01E1B05271A004D67D4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
4681C0291B05271A004D67D4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4681C02D1B05271A004D67D4 /* libToolTipMenu.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
4681C0181B05271A004D67D4 = {
isa = PBXGroup;
children = (
4681C0231B05271A004D67D4 /* ToolTipMenu */,
4681C0301B05271A004D67D4 /* ToolTipMenuTests */,
4681C0221B05271A004D67D4 /* Products */,
);
sourceTree = "<group>";
};
4681C0221B05271A004D67D4 /* Products */ = {
isa = PBXGroup;
children = (
4681C0211B05271A004D67D4 /* libToolTipMenu.a */,
4681C02C1B05271A004D67D4 /* ToolTipMenuTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
4681C0231B05271A004D67D4 /* ToolTipMenu */ = {
isa = PBXGroup;
children = (
4681C0241B05271A004D67D4 /* ToolTipMenu.h */,
4681C0261B05271A004D67D4 /* ToolTipMenu.m */,
469F58B31B069F9800C571E8 /* RCTToolTipText.h */,
469F58B61B069FF300C571E8 /* RCTToolTipText.m */,
469F58BA1B06A01D00C571E8 /* RCTToolTipTextManager.h */,
469F58B81B06A00C00C571E8 /* RCTToolTipTextManager.m */,
);
path = ToolTipMenu;
sourceTree = "<group>";
};
4681C0301B05271A004D67D4 /* ToolTipMenuTests */ = {
isa = PBXGroup;
children = (
4681C0311B05271A004D67D4 /* Supporting Files */,
);
path = ToolTipMenuTests;
sourceTree = "<group>";
};
4681C0311B05271A004D67D4 /* Supporting Files */ = {
isa = PBXGroup;
children = (
4681C0321B05271A004D67D4 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
4681C0201B05271A004D67D4 /* ToolTipMenu */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4681C0351B05271A004D67D4 /* Build configuration list for PBXNativeTarget "ToolTipMenu" */;
buildPhases = (
4681C01D1B05271A004D67D4 /* Sources */,
4681C01E1B05271A004D67D4 /* Frameworks */,
4681C01F1B05271A004D67D4 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = ToolTipMenu;
productName = ToolTipMenu;
productReference = 4681C0211B05271A004D67D4 /* libToolTipMenu.a */;
productType = "com.apple.product-type.library.static";
};
4681C02B1B05271A004D67D4 /* ToolTipMenuTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4681C0381B05271A004D67D4 /* Build configuration list for PBXNativeTarget "ToolTipMenuTests" */;
buildPhases = (
4681C0281B05271A004D67D4 /* Sources */,
4681C0291B05271A004D67D4 /* Frameworks */,
4681C02A1B05271A004D67D4 /* Resources */,
);
buildRules = (
);
dependencies = (
4681C02F1B05271A004D67D4 /* PBXTargetDependency */,
);
name = ToolTipMenuTests;
productName = ToolTipMenuTests;
productReference = 4681C02C1B05271A004D67D4 /* ToolTipMenuTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
4681C0191B05271A004D67D4 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0630;
ORGANIZATIONNAME = "Chirag Jain";
TargetAttributes = {
4681C0201B05271A004D67D4 = {
CreatedOnToolsVersion = 6.3.1;
};
4681C02B1B05271A004D67D4 = {
CreatedOnToolsVersion = 6.3.1;
};
};
};
buildConfigurationList = 4681C01C1B05271A004D67D4 /* Build configuration list for PBXProject "ToolTipMenu" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 4681C0181B05271A004D67D4;
productRefGroup = 4681C0221B05271A004D67D4 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
4681C0201B05271A004D67D4 /* ToolTipMenu */,
4681C02B1B05271A004D67D4 /* ToolTipMenuTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
4681C02A1B05271A004D67D4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
4681C01D1B05271A004D67D4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4681C0271B05271A004D67D4 /* ToolTipMenu.m in Sources */,
469F58B91B06A00C00C571E8 /* RCTToolTipTextManager.m in Sources */,
469F58B71B069FF300C571E8 /* RCTToolTipText.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4681C0281B05271A004D67D4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
4681C02F1B05271A004D67D4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4681C0201B05271A004D67D4 /* ToolTipMenu */;
targetProxy = 4681C02E1B05271A004D67D4 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
4681C0331B05271A004D67D4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.3;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
4681C0341B05271A004D67D4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.3;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
4681C0361B05271A004D67D4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native/**",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
4681C0371B05271A004D67D4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native/**",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
4681C0391B05271A004D67D4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = ToolTipMenuTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
4681C03A1B05271A004D67D4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
INFOPLIST_FILE = ToolTipMenuTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
4681C01C1B05271A004D67D4 /* Build configuration list for PBXProject "ToolTipMenu" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4681C0331B05271A004D67D4 /* Debug */,
4681C0341B05271A004D67D4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4681C0351B05271A004D67D4 /* Build configuration list for PBXNativeTarget "ToolTipMenu" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4681C0361B05271A004D67D4 /* Debug */,
4681C0371B05271A004D67D4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4681C0381B05271A004D67D4 /* Build configuration list for PBXNativeTarget "ToolTipMenuTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4681C0391B05271A004D67D4 /* Debug */,
4681C03A1B05271A004D67D4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 4681C0191B05271A004D67D4 /* Project object */;
}

View File

@ -0,0 +1,14 @@
#import <UIKit/UIKit.h>
#import "RCTText.h"
@class RCTEventDispatcher;
@interface RCTToolTipText : RCTText
@property(nonatomic, strong) RCTEventDispatcher *_eventDispatcher;
- (void)tappedMenuItem:(NSString *)text;
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
@end

View File

@ -0,0 +1,54 @@
#import "RCTToolTipText.h"
#import "RCTEventDispatcher.h"
#import "UIView+React.h"
@implementation RCTToolTipText
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
if ((self = [super initWithFrame:CGRectZero])) {
self._eventDispatcher = eventDispatcher;
}
return self;
}
- (BOOL) canBecomeFirstResponder
{
return YES;
}
- (void)tappedMenuItem:(NSString *)text {
[self._eventDispatcher sendTextEventWithType:RCTTextEventTypeChange
reactTag:self.reactTag
text:text];
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
NSString *sel = NSStringFromSelector(action);
NSRange match = [sel rangeOfString:@"magic_"];
if (match.location == 0) {
return YES;
}
return NO;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
if ([super methodSignatureForSelector:sel]) {
return [super methodSignatureForSelector:sel];
}
return [super methodSignatureForSelector:@selector(tappedMenuItem:)];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
NSString *sel = NSStringFromSelector([invocation selector]);
NSRange match = [sel rangeOfString:@"magic_"];
if (match.location == 0) {
[self tappedMenuItem:[sel substringFromIndex:6]];
} else {
[super forwardInvocation:invocation];
}
}
@end

View File

@ -0,0 +1,5 @@
#import "RCTTextManager.h"
@interface RCTToolTipTextManager : RCTTextManager
@end

View File

@ -0,0 +1,14 @@
#import "RCTToolTipTextManager.h"
#import "RCTToolTipText.h"
#import "RCTBridge.h"
@implementation RCTToolTipTextManager
RCT_EXPORT_MODULE()
- (UIView *)view
{
return [[RCTToolTipText alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
}
@end

View File

@ -0,0 +1,6 @@
#import <UIKit/UIKit.h>
#import "RCTBridgeModule.h"
@interface ToolTipMenu : NSObject <RCTBridgeModule>
@end

41
ToolTipMenu/ToolTipMenu.m Normal file
View File

@ -0,0 +1,41 @@
#import "ToolTipMenu.h"
#import "RCTToolTipText.h"
#import "RCTSparseArray.h"
#import "RCTUIManager.h"
@implementation ToolTipMenu
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
RCT_EXPORT_METHOD(show:(NSNumber *)reactTag
items: (NSArray *)items)
{
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
RCTToolTipText *view = viewRegistry[reactTag];
if (!view) {
RCTLogError(@"Cannot find view with tag #%@", reactTag);
return;
}
NSArray *buttons = items;
NSMutableArray *menuItems = [NSMutableArray array];
for (NSString *buttonText in buttons) {
NSString *sel = [NSString stringWithFormat:@"magic_%@", buttonText];
[menuItems addObject:[[UIMenuItem alloc]
initWithTitle:buttonText
action:NSSelectorFromString(sel)]];
}
[view becomeFirstResponder];
UIMenuController *menuCont = [UIMenuController sharedMenuController];
[menuCont setTargetRect:view.frame inView:view.superview];
menuCont.arrowDirection = UIMenuControllerArrowDown;
menuCont.menuItems = menuItems;
[menuCont setMenuVisible:YES animated:YES];
}];
}
@end

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>cj.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

220
ToolTipText.js Normal file
View File

@ -0,0 +1,220 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ToolTipText
* @flow
*/
'use strict';
var NativeMethodsMixin = require('NativeMethodsMixin');
var React = require('React');
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
var StyleSheetPropType = require('StyleSheetPropType');
var TextStylePropTypes = require('TextStylePropTypes');
var Touchable = require('Touchable');
var createReactNativeComponentClass =
require('createReactNativeComponentClass');
var merge = require('merge');
var stylePropType = StyleSheetPropType(TextStylePropTypes);
var viewConfig = {
validAttributes: merge(ReactNativeViewAttributes.UIView, {
isHighlighted: true,
numberOfLines: true,
}),
uiViewClassName: 'RCTToolTipText',
};
/**
* A React component for displaying text which supports nesting,
* styling, and touch handling. In the following example, the nested title and
* body text will inherit the `fontFamily` from `styles.baseText`, but the title
* provides its own additional styles. The title and body will stack on top of
* each other on account of the literal newlines:
*
* ```
* renderText: function() {
* return (
* <Text style={styles.baseText}>
* <Text style={styles.titleText} onPress={this.onPressTitle}>
* {this.state.titleText + '\n\n'}
* </Text>
* <Text numberOfLines={5}>
* {this.state.bodyText}
* </Text>
* </Text>
* );
* },
* ...
* var styles = StyleSheet.create({
* baseText: {
* fontFamily: 'Cochin',
* },
* titleText: {
* fontSize: 20,
* fontWeight: 'bold',
* },
* };
* ```
*/
var Text = React.createClass({
mixins: [Touchable.Mixin, NativeMethodsMixin],
propTypes: {
/**
* Used to truncate the text with an elipsis after computing the text
* layout, including line wrapping, such that the total number of lines does
* not exceed this number.
*/
numberOfLines: React.PropTypes.number,
/**
* This function is called on press. Text intrinsically supports press
* handling with a default highlight state (which can be disabled with
* `suppressHighlighting`).
*/
onPress: React.PropTypes.func,
/**
* Callback that is called when the text input's text changes.
*/
onChange: React.PropTypes.func,
/**
* When true, no visual change is made when text is pressed down. By
* default, a gray oval highlights the text on press down.
*/
suppressHighlighting: React.PropTypes.bool,
style: stylePropType,
/**
* Used to locate this view in end-to-end tests.
*/
testID: React.PropTypes.string,
/**
* Invoked on mount and layout changes with
*
* {nativeEvent: { layout: {x, y, width, height}}}.
*/
onLayout: React.PropTypes.func,
},
viewConfig: viewConfig,
getInitialState: function() {
return merge(this.touchableGetInitialState(), {
isHighlighted: false,
});
},
onStartShouldSetResponder: function(): bool {
var shouldSetFromProps = this.props.onStartShouldSetResponder &&
this.props.onStartShouldSetResponder();
return shouldSetFromProps || !!this.props.onPress;
},
/*
* Returns true to allow responder termination
*/
handleResponderTerminationRequest: function(): bool {
// Allow touchable or props.onResponderTerminationRequest to deny
// the request
var allowTermination = this.touchableHandleResponderTerminationRequest();
if (allowTermination && this.props.onResponderTerminationRequest) {
allowTermination = this.props.onResponderTerminationRequest();
}
return allowTermination;
},
handleResponderGrant: function(e: SyntheticEvent, dispatchID: string) {
this.touchableHandleResponderGrant(e, dispatchID);
this.props.onResponderGrant &&
this.props.onResponderGrant.apply(this, arguments);
},
handleResponderMove: function(e: SyntheticEvent) {
this.touchableHandleResponderMove(e);
this.props.onResponderMove &&
this.props.onResponderMove.apply(this, arguments);
},
handleResponderRelease: function(e: SyntheticEvent) {
this.touchableHandleResponderRelease(e);
this.props.onResponderRelease &&
this.props.onResponderRelease.apply(this, arguments);
},
handleResponderTerminate: function(e: SyntheticEvent) {
this.touchableHandleResponderTerminate(e);
this.props.onResponderTerminate &&
this.props.onResponderTerminate.apply(this, arguments);
},
touchableHandleActivePressIn: function() {
if (this.props.suppressHighlighting || !this.props.onPress) {
return;
}
this.setState({
isHighlighted: true,
});
},
touchableHandleActivePressOut: function() {
if (this.props.suppressHighlighting || !this.props.onPress) {
return;
}
this.setState({
isHighlighted: false,
});
},
touchableHandlePress: function() {
this.props.onPress && this.props.onPress();
},
touchableGetPressRectOffset: function(): RectOffset {
return PRESS_RECT_OFFSET;
},
_onChange: function(event: Event) {
this.props.onChange && this.props.onChange(event);
},
render: function() {
var props = {};
for (var key in this.props) {
props[key] = this.props[key];
}
// Text is accessible by default
if (props.accessible !== false) {
props.accessible = true;
}
props.isHighlighted = this.state.isHighlighted;
props.onStartShouldSetResponder = this.onStartShouldSetResponder;
props.onResponderTerminationRequest =
this.handleResponderTerminationRequest;
props.onResponderGrant = this.handleResponderGrant;
props.onResponderMove = this.handleResponderMove;
props.onResponderRelease = this.handleResponderRelease;
props.onResponderTerminate = this.handleResponderTerminate;
return <RCTText {...props} />;
},
});
type RectOffset = {
top: number;
left: number;
right: number;
bottom: number;
}
var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
var RCTText = createReactNativeComponentClass(viewConfig);
module.exports = Text;

25
package.json Normal file
View File

@ -0,0 +1,25 @@
{
"name": "react-native-tooltip",
"version": "0.1.0",
"description": "A react-native wrapper for showing tooltips",
"main": "ToolTipText.ios.js",
"author": {
"name": "Chirag Jain",
"email": "jain_chirag04@yahoo.com",
"url": "http://chiragjain.tumblr.com"
},
"repository": {
"type": "git",
"url": "git@github.com:chirag04/react-native-tooltip.git"
},
"keywords": [
"react",
"react-native",
"react-component",
"ios",
"tooltip",
],
"dependencies": {
"react-native": "^0.4.4"
}
}

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB