Files
react-native/Libraries/Alert/Alert.js
James Ide 0ee5f68929 Migrate "Libraries" from Haste to standard path-based requires (sans vendor & renderers) (#24749)
Summary:
This is the next step in moving RN towards standard path-based requires. All the requires in `Libraries` have been rewritten to use relative requires with a few exceptions, namely, `vendor` and `Renderer/oss` since those need to be changed upstream. This commit uses relative requires instead of `react-native/...` so that if Facebook were to stop syncing out certain folders and therefore remove code from the react-native package, internal code at Facebook would not need to change.

See the umbrella issue at https://github.com/facebook/react-native/issues/24316 for more detail.

[General] [Changed] - Migrate "Libraries" from Haste to standard path-based requires
Pull Request resolved: https://github.com/facebook/react-native/pull/24749

Differential Revision: D15258017

Pulled By: cpojer

fbshipit-source-id: a1f480ea36c05c659b6f37c8f02f6f9216d5a323
2019-05-08 08:48:59 -07:00

182 lines
5.2 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
const NativeModules = require('../BatchedBridge/NativeModules');
const RCTAlertManager = NativeModules.AlertManager;
const Platform = require('../Utilities/Platform');
export type Buttons = Array<{
text?: string,
onPress?: ?Function,
style?: AlertButtonStyle,
}>;
type Options = {
cancelable?: ?boolean,
onDismiss?: ?Function,
};
type AlertType = $Enum<{
default: string,
'plain-text': string,
'secure-text': string,
'login-password': string,
}>;
export type AlertButtonStyle = $Enum<{
default: string,
cancel: string,
destructive: string,
}>;
/**
* Launches an alert dialog with the specified title and message.
*
* See http://facebook.github.io/react-native/docs/alert.html
*/
class Alert {
static alert(
title: ?string,
message?: ?string,
buttons?: Buttons,
options?: Options,
): void {
if (Platform.OS === 'ios') {
Alert.prompt(title, message, buttons, 'default');
} else if (Platform.OS === 'android') {
let config = {
title: title || '',
message: message || '',
cancelable: false,
};
if (options) {
config = {...config, cancelable: options.cancelable};
}
// At most three buttons (neutral, negative, positive). Ignore rest.
// The text 'OK' should be probably localized. iOS Alert does that in native.
const validButtons: Buttons = buttons
? buttons.slice(0, 3)
: [{text: 'OK'}];
const buttonPositive = validButtons.pop();
const buttonNegative = validButtons.pop();
const buttonNeutral = validButtons.pop();
if (buttonNeutral) {
config = {...config, buttonNeutral: buttonNeutral.text || ''};
}
if (buttonNegative) {
config = {...config, buttonNegative: buttonNegative.text || ''};
}
if (buttonPositive) {
config = {...config, buttonPositive: buttonPositive.text || ''};
}
NativeModules.DialogManagerAndroid.showAlert(
config,
errorMessage => console.warn(errorMessage),
(action, buttonKey) => {
if (action === NativeModules.DialogManagerAndroid.buttonClicked) {
if (
buttonKey === NativeModules.DialogManagerAndroid.buttonNeutral
) {
buttonNeutral.onPress && buttonNeutral.onPress();
} else if (
buttonKey === NativeModules.DialogManagerAndroid.buttonNegative
) {
buttonNegative.onPress && buttonNegative.onPress();
} else if (
buttonKey === NativeModules.DialogManagerAndroid.buttonPositive
) {
buttonPositive.onPress && buttonPositive.onPress();
}
} else if (action === NativeModules.DialogManagerAndroid.dismissed) {
options && options.onDismiss && options.onDismiss();
}
},
);
}
}
static prompt(
title: ?string,
message?: ?string,
callbackOrButtons?: ?(((text: string) => void) | Buttons),
type?: ?AlertType = 'plain-text',
defaultValue?: string,
keyboardType?: string,
): void {
if (Platform.OS === 'ios') {
if (typeof type === 'function') {
console.warn(
'You passed a callback function as the "type" argument to Alert.prompt(). React Native is ' +
'assuming you want to use the deprecated Alert.prompt(title, defaultValue, buttons, callback) ' +
'signature. The current signature is Alert.prompt(title, message, callbackOrButtons, type, defaultValue, ' +
'keyboardType) and the old syntax will be removed in a future version.',
);
const callback = type;
RCTAlertManager.alertWithArgs(
{
title: title || '',
type: 'plain-text',
defaultValue: message,
},
(id, value) => {
callback(value);
},
);
return;
}
let callbacks = [];
const buttons = [];
let cancelButtonKey;
let destructiveButtonKey;
if (typeof callbackOrButtons === 'function') {
callbacks = [callbackOrButtons];
} else if (Array.isArray(callbackOrButtons)) {
callbackOrButtons.forEach((btn, index) => {
callbacks[index] = btn.onPress;
if (btn.style === 'cancel') {
cancelButtonKey = String(index);
} else if (btn.style === 'destructive') {
destructiveButtonKey = String(index);
}
if (btn.text || index < (callbackOrButtons || []).length - 1) {
const btnDef = {};
btnDef[index] = btn.text || '';
buttons.push(btnDef);
}
});
}
RCTAlertManager.alertWithArgs(
{
title: title || '',
message: message || undefined,
buttons,
type: type || undefined,
defaultValue,
cancelButtonKey,
destructiveButtonKey,
keyboardType,
},
(id, value) => {
const cb = callbacks[id];
cb && cb(value);
},
);
}
}
}
module.exports = Alert;