Skip to content

Commit 9257376

Browse files
committed
Add new TextInput examples and fix bugs
The issue with null backgroundColor causes weird behavior Currently disabled padding cell due to other bugs.
1 parent ef4213d commit 9257376

File tree

10 files changed

+125
-124
lines changed

10 files changed

+125
-124
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
language: objective-c
22

3-
osx_image: xcode7.2
3+
osx_image: xcode7.3
44

55
install:
66
- brew reinstall nvm

Examples/UIExplorer/TextInputExample.osx.js

Lines changed: 30 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,8 @@ var styles = StyleSheet.create({
294294
height: 26,
295295
borderWidth: 0.5,
296296
borderColor: '#0f0f0f',
297-
flex: 1,
298-
fontSize: 13,
299-
padding: 4,
297+
//flex: 1,
298+
fontSize: 13
300299
},
301300
multiline: {
302301
borderWidth: 0.5,
@@ -354,6 +353,22 @@ exports.displayName = (undefined: ?string);
354353
exports.title = '<TextInput>';
355354
exports.description = 'Single and multi-line text inputs.';
356355
exports.examples = [
356+
{
357+
title: 'Inverted background + placeholder + borderless',
358+
render: function() {
359+
return (
360+
<View style={{backgroundColor: '#555', height: 50, flex: 1, paddingTop: 4, paddingLeft: 10, justifyContent: 'center'}}>
361+
<TextInput
362+
style={[styles.default, {height: 20, backgroundColor: 'transparent', color: '#ddd'}]}
363+
bezeled={false}
364+
placeholder={'placeholder'}
365+
placeholderTextColor={'tomato'}
366+
accessibilityLabel="I am the accessibility label for text input"
367+
/>
368+
</View>
369+
);
370+
}
371+
},
357372
{
358373
title: 'Auto-focus',
359374
render: function() {
@@ -366,6 +381,18 @@ exports.examples = [
366381
);
367382
}
368383
},
384+
{
385+
title: 'Focus ring type = none',
386+
render: function() {
387+
return (
388+
<TextInput
389+
style={[styles.default]}
390+
focusRingType={'none'}
391+
accessibilityLabel="I am the accessibility label for text input"
392+
/>
393+
);
394+
}
395+
},
369396
{
370397
title: "Live Re-Write (<sp> -> '_') + maxLength",
371398
render: function() {
@@ -426,98 +453,6 @@ exports.examples = [
426453
);
427454
}
428455
},
429-
{
430-
title: 'Keyboard types',
431-
render: function() {
432-
var keyboardTypes = [
433-
'default',
434-
'ascii-capable',
435-
'numbers-and-punctuation',
436-
'url',
437-
'number-pad',
438-
'phone-pad',
439-
'name-phone-pad',
440-
'email-address',
441-
'decimal-pad',
442-
'twitter',
443-
'web-search',
444-
'numeric',
445-
];
446-
var examples = keyboardTypes.map((type) => {
447-
return (
448-
<WithLabel key={type} label={type}>
449-
<TextInput
450-
keyboardType={type}
451-
style={styles.default}
452-
/>
453-
</WithLabel>
454-
);
455-
});
456-
return <View>{examples}</View>;
457-
}
458-
},
459-
{
460-
title: 'Keyboard appearance',
461-
render: function() {
462-
var keyboardAppearance = [
463-
'default',
464-
'light',
465-
'dark',
466-
];
467-
var examples = keyboardAppearance.map((type) => {
468-
return (
469-
<WithLabel key={type} label={type}>
470-
<TextInput
471-
keyboardAppearance={type}
472-
style={styles.default}
473-
/>
474-
</WithLabel>
475-
);
476-
});
477-
return <View>{examples}</View>;
478-
}
479-
},
480-
{
481-
title: 'Return key types',
482-
render: function() {
483-
var returnKeyTypes = [
484-
'default',
485-
'go',
486-
'google',
487-
'join',
488-
'next',
489-
'route',
490-
'search',
491-
'send',
492-
'yahoo',
493-
'done',
494-
'emergency-call',
495-
];
496-
var examples = returnKeyTypes.map((type) => {
497-
return (
498-
<WithLabel key={type} label={type}>
499-
<TextInput
500-
returnKeyType={type}
501-
style={styles.default}
502-
/>
503-
</WithLabel>
504-
);
505-
});
506-
return <View>{examples}</View>;
507-
}
508-
},
509-
{
510-
title: 'Enable return key automatically',
511-
render: function() {
512-
return (
513-
<View>
514-
<WithLabel label="true">
515-
<TextInput enablesReturnKeyAutomatically={true} style={styles.default} />
516-
</WithLabel>
517-
</View>
518-
);
519-
}
520-
},
521456
{
522457
title: 'Secure text entry',
523458
render: function() {

Libraries/Components/TextInput/TextInput.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,15 @@ var TextInput = React.createClass({
135135
'done',
136136
'emergency-call',
137137
]),
138+
/**
139+
* Determines the color of the keyboard.
140+
* @platform osx
141+
*/
142+
focusRingType: PropTypes.oneOf([
143+
'default',
144+
'none',
145+
'exterior',
146+
]),
138147
/**
139148
* Limits the maximum number of characters that can be entered. Use this
140149
* instead of implementing the logic in JS to avoid flicker.
@@ -200,6 +209,10 @@ var TextInput = React.createClass({
200209
* The text color of the placeholder string
201210
*/
202211
placeholderTextColor: PropTypes.string,
212+
/**
213+
* The color used by caret and selection
214+
*/
215+
selectionColor: PropTypes.string,
203216
/**
204217
* If true, the text input obscures the text entered so that sensitive text
205218
* like passwords stay secure. The default value is false.
@@ -433,7 +446,7 @@ var TextInput = React.createClass({
433446
text={this._getText()}
434447
/>;
435448
}
436-
449+
437450
return (
438451
<TouchableWithoutFeedback
439452
onPress={this._onPress}

Libraries/Text/RCTText.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#import <AppKit/AppKit.h>
1111

12+
CGRect UIEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets);
13+
1214
@interface RCTText : NSView
1315

1416
@property (nonatomic, assign) NSEdgeInsets contentInset;

Libraries/Text/RCTText.m

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414
#import "NSView+React.h"
1515
#import <QuartzCore/CAShapeLayer.h>
1616

17+
// https://github.com/BigZaphod/Chameleon/blob/84605ede274bd82b330d72dd6ac41e64eb925fd7/UIKit/Classes/UIGeometry.h
18+
CGRect UIEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) {
19+
rect.origin.x += insets.left;
20+
rect.origin.y += insets.top;
21+
rect.size.width -= (insets.left + insets.right);
22+
rect.size.height -= (insets.top + insets.bottom);
23+
return rect;
24+
}
25+
1726
@implementation NSBezierPath (BezierPathQuartzUtilities)
1827
// This method works only in OS X v10.2 and later.
1928
- (CGPathRef)quartzPath
@@ -134,15 +143,6 @@ - (void)setTextStorage:(NSTextStorage *)textStorage
134143
[self setNeedsDisplay:YES];
135144
}
136145

137-
// https://github.com/BigZaphod/Chameleon/blob/84605ede274bd82b330d72dd6ac41e64eb925fd7/UIKit/Classes/UIGeometry.h
138-
static inline CGRect UIEdgeInsetsInsetRect(CGRect rect, NSEdgeInsets insets) {
139-
rect.origin.x += insets.left;
140-
rect.origin.y += insets.top;
141-
rect.size.width -= (insets.left + insets.right);
142-
rect.size.height -= (insets.top + insets.bottom);
143-
return rect;
144-
}
145-
146146
- (void)drawRect:(CGRect)dirtyRect
147147
{
148148
NSLayoutManager *layoutManager = _textStorage.layoutManagers.firstObject;

Libraries/Text/RCTTextField.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
@class RCTEventDispatcher;
1515

16+
@interface TextFieldCellWithPaddings : NSTextFieldCell
17+
@end
18+
1619
@interface RCTTextField : NSTextField <NSTextFieldDelegate>
1720

1821
@property (nonatomic, assign) BOOL caretHidden;

Libraries/Text/RCTTextField.m

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,54 @@
1313
#import "RCTEventDispatcher.h"
1414
#import "RCTUtils.h"
1515
#import "NSView+React.h"
16+
#import "RCTText.h"
17+
18+
19+
//
20+
//@implementation TextFieldCellWithPaddings
21+
//
22+
//- (id)init
23+
//{
24+
// self = [super init];
25+
// if (self) {
26+
//// self.bordered = NO;
27+
//// self.drawsBackground = NO;
28+
// }
29+
// return self;
30+
//}
31+
//
32+
////- (NSRect)titleRectForBounds:(NSRect)theRect
33+
////{
34+
//// //NSRect titleFrame = [super titleRectForBounds:theRect];
35+
////
36+
//// //NSSize titleSize = [[self attributedStringValue] size];
37+
//// //titleFrame.origin.y = theRect.origin.y + (theRect.size.height - titleSize.height) / 2.0;
38+
//// return UIEdgeInsetsInsetRect(theRect, ((RCTTextField *)[self controlView]).contentInset);
39+
////}
40+
//
41+
//- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
42+
// NSRect titleRect = [self titleRectForBounds:cellFrame];
43+
// [[self attributedStringValue] drawInRect:titleRect];
44+
//}
45+
//
46+
//
47+
////- (NSRect)drawingRectForBounds:(NSRect)rect
48+
////{
49+
//// NSRect rectInset = UIEdgeInsetsInsetRect(rect, _contentInset);
50+
//// return [super drawingRectForBounds:rectInset];
51+
////}
52+
//
53+
//// Required methods
54+
//- (id)initWithCoder:(NSCoder *)decoder {
55+
// return [super initWithCoder:decoder];
56+
//}
57+
//- (id)initImageCell:(NSImage *)image {
58+
// return [super initImageCell:image];
59+
//}
60+
//- (id)initTextCell:(NSString *)string {
61+
// return [super initTextCell:string];
62+
//}
63+
//@end
1664

1765
@implementation RCTTextField
1866
{
@@ -37,8 +85,9 @@ - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
3785

3886
_eventDispatcher = eventDispatcher;
3987
_previousSelectionRange = self.currentEditor.selectedRange;
40-
[self addObserver:self forKeyPath:@"selectedTextRange" options:0 context:nil];
4188
_reactSubviews = [NSMutableArray new];
89+
90+
[self addObserver:self forKeyPath:@"selectedTextRange" options:0 context:nil];
4291
}
4392
return self;
4493
}
@@ -60,8 +109,6 @@ - (void)sendKeyValueForString:(NSString *)string
60109
eventCount:_nativeEventCount];
61110
}
62111

63-
64-
65112
// This method is overridden for `onKeyPress`. The manager
66113
// will not send a keyPress for text that was pasted.
67114
- (void)paste:(id)sender
@@ -70,14 +117,6 @@ - (void)paste:(id)sender
70117
[[super currentEditor] paste:sender];
71118
}
72119

73-
- (void)setInsertionPointColor:(NSColor *)color
74-
{
75-
NSTextView* textField = (NSTextView*) [self currentEditor];
76-
if( [textField respondsToSelector: @selector(setInsertionPointColor:)] ) {
77-
[textField setInsertionPointColor: [NSColor blueColor]];
78-
}
79-
}
80-
81120
- (void)setText:(NSString *)text
82121
{
83122
NSInteger eventLag = _nativeEventCount - _mostRecentEventCount;
@@ -108,6 +147,7 @@ - (void)updatePlaceholder
108147
[self setPlaceholderAttributedString:attrString];
109148
}
110149
}
150+
111151
- (void)setPlaceholder:(NSString *)placeholder
112152
{
113153
if (placeholder != nil && ![_placeholderString isEqual:placeholder]) {
@@ -116,6 +156,14 @@ - (void)setPlaceholder:(NSString *)placeholder
116156
}
117157
}
118158

159+
- (void)setBackgroundColor:(NSString *)backgroundColor
160+
{
161+
if (backgroundColor) {
162+
[self setDrawsBackground:YES];
163+
[self.cell setBackgroundColor:backgroundColor];
164+
}
165+
}
166+
119167
- (NSArray<NSView *> *)reactSubviews
120168
{
121169
// TODO: do we support subviews of textfield in React?

Libraries/Text/RCTTextFieldManager.m

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ - (RCTViewManagerUIBlock)uiBlockToAmendWithShadowView:(RCTShadowView *)shadowVie
102102
NSNumber *reactTag = shadowView.reactTag;
103103
NSEdgeInsets padding = shadowView.paddingAsInsets;
104104
return ^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RCTTextField *> *viewRegistry) {
105-
viewRegistry[reactTag].contentInset = padding;
105+
((RCTTextField *)viewRegistry[reactTag]).contentInset = padding;
106106
};
107107
}
108108

@@ -118,10 +118,8 @@ - (RCTViewManagerUIBlock)uiBlockToAmendWithShadowView:(RCTShadowView *)shadowVie
118118
@end
119119

120120
@interface RCTSecureTextFieldManager() <NSTextFieldDelegate>
121-
122121
@end
123122

124-
125123
// TODO: extract common logic into one place
126124
@implementation RCTSecureTextFieldManager
127125

0 commit comments

Comments
 (0)