[ReactNative] Add prompt to AlertIOS
Summary: Add `AlertIOS.prompt` It's compatible with the js spec, with the exception that I had to add a callback param since it's async. Also supports the same button configuration as `AlertIOS.alert`. @public Test Plan: I've updated the `AlertIOS` example on UIExplorer with every valid combination of parameters, so just going through it should be fine.
This commit is contained in:
parent
cfeae15c1f
commit
ef339250b5
|
@ -95,9 +95,98 @@ exports.examples = [{
|
|||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Prompt',
|
||||
render(): React.Component {
|
||||
return <PromptExample />
|
||||
}
|
||||
}];
|
||||
|
||||
class PromptExample extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.promptResponse = this.promptResponse.bind(this);
|
||||
this.state = {
|
||||
promptValue: undefined,
|
||||
};
|
||||
|
||||
this.title = 'Type a value';
|
||||
this.defaultValue = 'Default value';
|
||||
this.buttons = [{
|
||||
text: 'Custom cancel',
|
||||
}, {
|
||||
text: 'Custom OK',
|
||||
onPress: this.promptResponse
|
||||
}];
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text style={{marginBottom: 10}}>
|
||||
<Text style={{fontWeight: 'bold'}}>Prompt value:</Text> {this.state.promptValue}
|
||||
</Text>
|
||||
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this.prompt.bind(this, this.title, this.promptResponse)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
prompt with title & callback
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this.prompt.bind(this, this.title, this.buttons)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
prompt with title & custom buttons
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this.prompt.bind(this, this.title, this.defaultValue, this.promptResponse)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
prompt with title, default value & callback
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={this.prompt.bind(this, this.title, this.defaultValue, this.buttons)}>
|
||||
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
prompt with title, default value & custom buttons
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
prompt() {
|
||||
// Flow's apply support is broken: #7035621
|
||||
((AlertIOS.prompt: any).apply: any)(AlertIOS, arguments);
|
||||
}
|
||||
|
||||
promptResponse(promptValue) {
|
||||
this.setState({ promptValue });
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
wrapper: {
|
||||
borderRadius: 5,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
'use strict';
|
||||
|
||||
var RCTAlertManager = require('NativeModules').AlertManager;
|
||||
var invariant = require('invariant');
|
||||
|
||||
var DEFAULT_BUTTON_TEXT = 'OK';
|
||||
var DEFAULT_BUTTON = {
|
||||
|
@ -47,14 +48,17 @@ class AlertIOS {
|
|||
message?: ?string,
|
||||
buttons?: Array<{
|
||||
text: ?string;
|
||||
onPress: ?Function;
|
||||
}>
|
||||
onPress?: ?Function;
|
||||
}>,
|
||||
type?: ?string
|
||||
): void {
|
||||
var callbacks = [];
|
||||
var buttonsSpec = [];
|
||||
title = title || '';
|
||||
message = message || '';
|
||||
buttons = buttons || [DEFAULT_BUTTON];
|
||||
type = type || '';
|
||||
|
||||
buttons.forEach((btn, index) => {
|
||||
callbacks[index] = btn.onPress;
|
||||
var btnDef = {};
|
||||
|
@ -65,12 +69,50 @@ class AlertIOS {
|
|||
title,
|
||||
message,
|
||||
buttons: buttonsSpec,
|
||||
}, (id) => {
|
||||
type,
|
||||
}, (id, value) => {
|
||||
var cb = callbacks[id];
|
||||
cb && cb();
|
||||
cb && cb(value);
|
||||
});
|
||||
}
|
||||
|
||||
static prompt(
|
||||
title: string,
|
||||
value?: string,
|
||||
buttons?: Array<{
|
||||
text: ?string;
|
||||
onPress?: ?Function;
|
||||
}>,
|
||||
callback?: ?Function
|
||||
): void {
|
||||
if (arguments.length === 2) {
|
||||
if (typeof value === 'object') {
|
||||
buttons = value;
|
||||
value = undefined;
|
||||
} else if (typeof value === 'function') {
|
||||
callback = value;
|
||||
value = undefined;
|
||||
}
|
||||
} else if (arguments.length === 3 && typeof buttons === 'function') {
|
||||
callback = buttons;
|
||||
buttons = undefined;
|
||||
}
|
||||
|
||||
invariant(
|
||||
!(callback && buttons) && (callback || buttons),
|
||||
'Must provide either a button list or a callback, but not both'
|
||||
);
|
||||
|
||||
if (!buttons) {
|
||||
buttons = [{
|
||||
text: 'Cancel',
|
||||
}, {
|
||||
text: 'OK',
|
||||
onPress: callback
|
||||
}];
|
||||
}
|
||||
this.alert(title, value, buttons, 'plain-text');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AlertIOS;
|
||||
|
|
|
@ -59,6 +59,7 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
|||
{
|
||||
NSString *title = args[@"title"];
|
||||
NSString *message = args[@"message"];
|
||||
NSString *type = args[@"type"];
|
||||
NSArray *buttons = args[@"buttons"];
|
||||
|
||||
if (!title && !message) {
|
||||
|
@ -70,13 +71,20 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
|||
}
|
||||
|
||||
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
|
||||
message:message
|
||||
message:nil
|
||||
delegate:self
|
||||
cancelButtonTitle:nil
|
||||
otherButtonTitles:nil];
|
||||
|
||||
NSMutableArray *buttonKeys = [[NSMutableArray alloc] initWithCapacity:buttons.count];
|
||||
|
||||
if ([type isEqualToString:@"plain-text"]) {
|
||||
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
|
||||
[alertView textFieldAtIndex:0].text = message;
|
||||
} else {
|
||||
alertView.message = message;
|
||||
}
|
||||
|
||||
NSInteger index = 0;
|
||||
for (NSDictionary *button in buttons) {
|
||||
if (button.count != 1) {
|
||||
|
@ -108,7 +116,15 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
|
|||
|
||||
RCTResponseSenderBlock callback = _alertCallbacks[index];
|
||||
NSArray *buttonKeys = _alertButtonKeys[index];
|
||||
callback(@[buttonKeys[buttonIndex]]);
|
||||
NSArray *args;
|
||||
|
||||
if (alertView.alertViewStyle == UIAlertViewStylePlainTextInput) {
|
||||
args = @[buttonKeys[buttonIndex], [alertView textFieldAtIndex:0].text];
|
||||
} else {
|
||||
args = @[buttonKeys[buttonIndex]];
|
||||
}
|
||||
|
||||
callback(args);
|
||||
|
||||
[_alerts removeObjectAtIndex:index];
|
||||
[_alertCallbacks removeObjectAtIndex:index];
|
||||
|
|
Loading…
Reference in New Issue