@nativescript-community/ui-dialogs 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/LICENSE +201 -0
- package/README.md +189 -2
- package/index-common.d.ts +27 -0
- package/index-common.js +5 -0
- package/index-common.js.map +1 -0
- package/index.android.d.ts +16 -0
- package/index.android.js +581 -0
- package/index.android.js.map +1 -0
- package/index.d.ts +129 -0
- package/index.ios.d.ts +33 -0
- package/index.ios.js +535 -0
- package/index.ios.js.map +1 -0
- package/package.json +50 -5
- package/platforms/android/native-api-usage.json +15 -0
- package/platforms/android/res/values/dialogsstyle.xml +7 -0
- package/platforms/ios/native-api-usage.json +11 -0
- package/tsconfig.tsbuildinfo +1 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dialogs component: same API as the core dialogs with custom views, custom buttons and more.
|
|
3
|
+
* Android uses Material dialogs. iOS uses the native UIAlertController (styling options are no-op).
|
|
4
|
+
* @module @nativescript-community/ui-dialogs
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/* eslint-disable no-redeclare */
|
|
8
|
+
/* eslint-disable @typescript-eslint/unified-signatures */
|
|
9
|
+
import { ActionOptions, AlertOptions, ConfirmOptions, LoginResult, PromptResult, LoginOptions as TNSLoginOptions, PromptOptions as TNSPromptOptions } from '@nativescript/core';
|
|
10
|
+
import { TextField, TextFieldProperties } from '@nativescript-community/ui-textfield';
|
|
11
|
+
import { MDCAlertControlerOptions } from './index-common';
|
|
12
|
+
|
|
13
|
+
export interface PromptOptions extends TNSPromptOptions {
|
|
14
|
+
autoFocus?: boolean;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Gets or sets the hint text to display in the input box.
|
|
18
|
+
*/
|
|
19
|
+
hintText?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Gets or sets the helper text to display in the input box.
|
|
22
|
+
*/
|
|
23
|
+
helperText?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Optional object to set any property to the textfield!
|
|
26
|
+
*/
|
|
27
|
+
textFieldProperties?: Partial<TextFieldProperties>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface LoginOptions extends TNSLoginOptions {
|
|
31
|
+
autoFocus?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Gets or sets the default text to display as hint in the user name input box.
|
|
34
|
+
*/
|
|
35
|
+
userNameHint?: string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Gets or sets the default text to display as hint in the password input box.
|
|
39
|
+
*/
|
|
40
|
+
passwordHint?: string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Optional object to set any property to the username textfield!
|
|
44
|
+
*/
|
|
45
|
+
usernameTextFieldProperties?: Partial<TextFieldProperties>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Optional object to set any property to the username textfield!
|
|
49
|
+
*/
|
|
50
|
+
passwordTextFieldProperties?: Partial<TextFieldProperties>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Optional function to choose if you can validate or not
|
|
54
|
+
*/
|
|
55
|
+
beforeShow?: (options: LoginOptions & MDCAlertControlerOptions, usernameTextField: TextField, passwordTextField: TextField) => void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { MDCAlertControlerOptions };
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The alert() method displays an alert box with a specified message.
|
|
62
|
+
* @param message Specifies the text to display in the alert box.
|
|
63
|
+
*/
|
|
64
|
+
export function alert(message: string | number | boolean): Promise<void>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The alert() method displays an alert box with a specified message.
|
|
68
|
+
* @param options Specifies the options for the alert box.
|
|
69
|
+
*/
|
|
70
|
+
export function alert(options: AlertOptions & MDCAlertControlerOptions): Promise<any>;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The confirm() method displays a dialog box with a specified message.
|
|
74
|
+
* @param message Specifies the text to display in the confirm box.
|
|
75
|
+
*/
|
|
76
|
+
export function confirm(message: string): Promise<boolean>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The confirm() method displays a dialog box with a specified message.
|
|
80
|
+
* @param options Specifies the options for the confirm box.
|
|
81
|
+
*/
|
|
82
|
+
export function confirm(options: ConfirmOptions & MDCAlertControlerOptions): Promise<boolean>;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The prompt() method displays a dialog box that prompts the visitor for input.
|
|
86
|
+
* @param message The text to display in the dialog box.
|
|
87
|
+
* @param defaultText The default text to display in the input box. Optional.
|
|
88
|
+
*/
|
|
89
|
+
export function prompt(message: string, defaultText?: string): Promise<PromptResult>;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The prompt() method displays a dialog box that prompts the visitor for input.
|
|
93
|
+
* @param options The options for the dialog box.
|
|
94
|
+
*/
|
|
95
|
+
export function prompt(options: PromptOptions & MDCAlertControlerOptions): Promise<PromptResult>;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The login() method displays a login dialog box that prompts the visitor for user name and password.
|
|
99
|
+
* @param message The text to display in the dialog box.
|
|
100
|
+
* @param userName The default text to display in the user name input box. Optional.
|
|
101
|
+
* @param password The default text to display in the password input box. Optional.
|
|
102
|
+
*/
|
|
103
|
+
export function login(message: string, userName?: string, password?: string): Promise<LoginResult>;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The login() method displays a login dialog box that prompts the visitor for user name and password.
|
|
107
|
+
* @param options The options for the dialog box.
|
|
108
|
+
*/
|
|
109
|
+
export function login(options: LoginOptions & MDCAlertControlerOptions): Promise<LoginResult>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The action() method displays a action box that prompts the visitor to choose some action.
|
|
113
|
+
* @param message The text to display in the dialog box.
|
|
114
|
+
* @param cancelButtonText The text to display in the cancel button.
|
|
115
|
+
* @param actions List of available actions.
|
|
116
|
+
*/
|
|
117
|
+
export function action(message: string, cancelButtonText: string, actions: string[]): Promise<string>;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* The action() method displays a action box that prompts the visitor to choose some action.
|
|
121
|
+
* @param options The options for the dialog box.
|
|
122
|
+
*/
|
|
123
|
+
export function action(options: ActionOptions & MDCAlertControlerOptions): Promise<string>;
|
|
124
|
+
|
|
125
|
+
export class AlertDialog {
|
|
126
|
+
constructor(options: AlertOptions & MDCAlertControlerOptions);
|
|
127
|
+
show(resolve?);
|
|
128
|
+
async hide();
|
|
129
|
+
}
|
package/index.ios.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { TextField } from '@nativescript-community/ui-textfield';
|
|
2
|
+
import { LoginResult, PromptResult, View, capitalizationType, inputType } from '@nativescript/core';
|
|
3
|
+
export { capitalizationType, inputType };
|
|
4
|
+
declare class UIViewAutoSize extends UIView {
|
|
5
|
+
_view: View;
|
|
6
|
+
contentHeightForWidth(width: number): number;
|
|
7
|
+
layoutSubviews(): void;
|
|
8
|
+
}
|
|
9
|
+
declare class ContentViewController extends UIViewController {
|
|
10
|
+
_container: UIViewAutoSize;
|
|
11
|
+
static initWithView(view: View): ContentViewController;
|
|
12
|
+
viewDidLayoutSubviews(): void;
|
|
13
|
+
}
|
|
14
|
+
interface AlertController extends UIAlertController {
|
|
15
|
+
autoFocusTextField?: TextField;
|
|
16
|
+
clear?: Function;
|
|
17
|
+
_resolveFunction?: Function;
|
|
18
|
+
_contentController?: ContentViewController;
|
|
19
|
+
}
|
|
20
|
+
export declare function alert(arg: any): Promise<any>;
|
|
21
|
+
export declare class AlertDialog {
|
|
22
|
+
private options;
|
|
23
|
+
alertController: AlertController;
|
|
24
|
+
presentingController: UIViewController;
|
|
25
|
+
constructor(options: any);
|
|
26
|
+
show(onClosed?: any): void;
|
|
27
|
+
hiding: boolean;
|
|
28
|
+
hide(result?: any): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
export declare function confirm(arg: any): Promise<boolean>;
|
|
31
|
+
export declare function prompt(...args: any[]): Promise<PromptResult>;
|
|
32
|
+
export declare function login(...args: any[]): Promise<LoginResult>;
|
|
33
|
+
export declare function action(...args: any[]): Promise<string>;
|
package/index.ios.js
ADDED
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
import { TextField } from '@nativescript-community/ui-textfield';
|
|
2
|
+
import { Application, Builder, CSSUtils, DialogStrings, Screen, StackLayout, Trace, Utils, View, capitalizationType, fromObject, getCurrentPage, inputType } from '@nativescript/core';
|
|
3
|
+
import { isDialogOptions, showingDialogs } from './index-common';
|
|
4
|
+
export { capitalizationType, inputType };
|
|
5
|
+
/**
|
|
6
|
+
* iOS: native UIAlertController (Liquid Glass on iOS 26+ for free).
|
|
7
|
+
* Supported: title, message, buttons, prompt, login, action (action sheet), custom `view`/`messageView`/`stackViewHolder`,
|
|
8
|
+
* `closeCallback`, `shouldResolveOnAction`, `AlertDialog.hide()`.
|
|
9
|
+
* No-op: all the styling options (colors, fonts, cornerRadius, elevation, scrimColor, titleIcon...), `dismissOnBackgroundTap`
|
|
10
|
+
* (UIKit alerts are not dismissed by a tap outside).
|
|
11
|
+
*
|
|
12
|
+
* UIAlertController has no public API to show a custom view: the view is hosted in a content view controller
|
|
13
|
+
* set through the `contentViewController` key (widely used but not documented by Apple).
|
|
14
|
+
* If UIKit refuses it the custom view is not shown and a warning is logged.
|
|
15
|
+
*/
|
|
16
|
+
const ALERT_WIDTH = 270; // width of a regular UIAlertController
|
|
17
|
+
var UIViewAutoSize = /** @class */ (function (_super) {
|
|
18
|
+
__extends(UIViewAutoSize, _super);
|
|
19
|
+
function UIViewAutoSize() {
|
|
20
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
21
|
+
}
|
|
22
|
+
UIViewAutoSize.prototype.contentHeightForWidth = function (width) {
|
|
23
|
+
var view = this._view;
|
|
24
|
+
if (!view) {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
var widthSpec = Utils.layout.makeMeasureSpec(Utils.layout.toDevicePixels(width), Utils.layout.EXACTLY);
|
|
28
|
+
var heightSpec = Utils.layout.makeMeasureSpec(Screen.mainScreen.heightPixels, Utils.layout.AT_MOST);
|
|
29
|
+
var measuredSize = View.measureChild(null, view, widthSpec, heightSpec);
|
|
30
|
+
return Utils.layout.toDeviceIndependentPixels(measuredSize.measuredHeight);
|
|
31
|
+
};
|
|
32
|
+
UIViewAutoSize.prototype.layoutSubviews = function () {
|
|
33
|
+
var view = this._view;
|
|
34
|
+
if (!view) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
var size = this.frame.size;
|
|
38
|
+
View.layoutChild(null, view, 0, 0, Utils.layout.toDevicePixels(size.width), Utils.layout.toDevicePixels(size.height));
|
|
39
|
+
};
|
|
40
|
+
return UIViewAutoSize;
|
|
41
|
+
}(UIView));
|
|
42
|
+
var ContentViewController = /** @class */ (function (_super) {
|
|
43
|
+
__extends(ContentViewController, _super);
|
|
44
|
+
function ContentViewController() {
|
|
45
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
46
|
+
}
|
|
47
|
+
ContentViewController.initWithView = function (view) {
|
|
48
|
+
var controller = ContentViewController.new();
|
|
49
|
+
view._setupAsRootView({});
|
|
50
|
+
view.parent = Application.getRootView();
|
|
51
|
+
view._isAddedToNativeVisualTree = true;
|
|
52
|
+
var container = UIViewAutoSize.new();
|
|
53
|
+
container._view = view;
|
|
54
|
+
container.addSubview(view.nativeViewProtected);
|
|
55
|
+
view.nativeViewProtected.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
|
|
56
|
+
controller._container = container;
|
|
57
|
+
controller.view = container;
|
|
58
|
+
// viewDidLoad is not called when the view is set manually: load the NativeScript view now
|
|
59
|
+
if (!view.isLoaded) {
|
|
60
|
+
view.callLoaded();
|
|
61
|
+
}
|
|
62
|
+
controller.preferredContentSize = CGSizeMake(ALERT_WIDTH, container.contentHeightForWidth(ALERT_WIDTH));
|
|
63
|
+
return controller;
|
|
64
|
+
};
|
|
65
|
+
ContentViewController.prototype.viewDidLayoutSubviews = function () {
|
|
66
|
+
_super.prototype.viewDidLayoutSubviews.call(this);
|
|
67
|
+
var container = this._container;
|
|
68
|
+
if (container) {
|
|
69
|
+
var height = container.contentHeightForWidth(this.view.bounds.size.width || ALERT_WIDTH);
|
|
70
|
+
if (height !== this.preferredContentSize.height) {
|
|
71
|
+
this.preferredContentSize = CGSizeMake(this.preferredContentSize.width, height);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
return ContentViewController;
|
|
76
|
+
}(UIViewController));
|
|
77
|
+
function createAlertController(options, resolve, style = 1 /* UIAlertControllerStyle.Alert */) {
|
|
78
|
+
const alertController = UIAlertController.alertControllerWithTitleMessagePreferredStyle(options.title || null, options.message || null, style);
|
|
79
|
+
alertController['isAlertController'] = true;
|
|
80
|
+
const clear = (alertController.clear = function clear() {
|
|
81
|
+
const index = showingDialogs.indexOf(alertController);
|
|
82
|
+
if (index !== -1) {
|
|
83
|
+
showingDialogs.splice(index, 1);
|
|
84
|
+
}
|
|
85
|
+
alertController._resolveFunction = null;
|
|
86
|
+
const contentController = alertController._contentController;
|
|
87
|
+
if (contentController && contentController._container) {
|
|
88
|
+
const view = contentController._container._view;
|
|
89
|
+
if (view) {
|
|
90
|
+
view.callUnloaded();
|
|
91
|
+
view._tearDownUI(true);
|
|
92
|
+
view.parent = null;
|
|
93
|
+
view._isAddedToNativeVisualTree = false;
|
|
94
|
+
}
|
|
95
|
+
contentController._container._view = null;
|
|
96
|
+
alertController._contentController = null;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
if (options.view) {
|
|
100
|
+
const view = options.view instanceof View
|
|
101
|
+
? options.view
|
|
102
|
+
: Builder.createViewFromEntry({
|
|
103
|
+
moduleName: options.view
|
|
104
|
+
});
|
|
105
|
+
if (view.parent) {
|
|
106
|
+
view.parent._removeView(view);
|
|
107
|
+
}
|
|
108
|
+
view.cssClasses.add(CSSUtils.MODAL_ROOT_VIEW_CSS_CLASS);
|
|
109
|
+
const modalRootViewCssClasses = CSSUtils.getSystemCssClasses();
|
|
110
|
+
modalRootViewCssClasses.forEach((c) => view.cssClasses.add(c));
|
|
111
|
+
alertController._resolveFunction = resolve;
|
|
112
|
+
const context = options.context || {};
|
|
113
|
+
context.closeCallback = function (originalArgs) {
|
|
114
|
+
if (alertController._resolveFunction) {
|
|
115
|
+
alertController._resolveFunction(originalArgs);
|
|
116
|
+
alertController._resolveFunction = null;
|
|
117
|
+
}
|
|
118
|
+
alertController.dismissViewControllerAnimatedCompletion(true, () => {
|
|
119
|
+
clear();
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
view.bindingContext = fromObject(context);
|
|
123
|
+
const contentController = ContentViewController.initWithView(view);
|
|
124
|
+
try {
|
|
125
|
+
// the only way to host a custom view in a UIAlertController
|
|
126
|
+
alertController.setValueForKey(contentController, 'contentViewController');
|
|
127
|
+
alertController._contentController = contentController;
|
|
128
|
+
view.viewController = alertController; // needed to prevent a crash in layoutChild
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
Trace.write(`custom view could not be set on the UIAlertController: ${err}`, Trace.categories.Error, Trace.messageType.error);
|
|
132
|
+
clear();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return alertController;
|
|
136
|
+
}
|
|
137
|
+
function addButtonsToAlertController(alertController, options, callback, validationArgs) {
|
|
138
|
+
if (!options) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
let onDoneCalled = false;
|
|
142
|
+
function raiseCallback(callback, result) {
|
|
143
|
+
if (options && options.shouldResolveOnAction && !options.shouldResolveOnAction(validationArgs ? validationArgs(result) : result)) {
|
|
144
|
+
// UIAlertController always dismisses on an action: show it again
|
|
145
|
+
setTimeout(() => showUIAlertController(alertController, options));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (onDoneCalled) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
onDoneCalled = true;
|
|
152
|
+
if (Utils.isFunction(callback)) {
|
|
153
|
+
callback(result);
|
|
154
|
+
}
|
|
155
|
+
alertController.clear();
|
|
156
|
+
}
|
|
157
|
+
function addButton(title, style, result) {
|
|
158
|
+
alertController.addAction(UIAlertAction.actionWithTitleStyleHandler(title, style, () => {
|
|
159
|
+
raiseCallback(callback, result);
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
if (Utils.isString(options.neutralButtonText)) {
|
|
163
|
+
addButton(options.neutralButtonText, 0 /* UIAlertActionStyle.Default */, undefined);
|
|
164
|
+
}
|
|
165
|
+
if (Utils.isString(options.okButtonText)) {
|
|
166
|
+
addButton(options.okButtonText, 0 /* UIAlertActionStyle.Default */, true);
|
|
167
|
+
}
|
|
168
|
+
if (Utils.isString(options.cancelButtonText)) {
|
|
169
|
+
// the cancel style is always displayed in the "cancel" position by UIKit
|
|
170
|
+
addButton(options.cancelButtonText, 1 /* UIAlertActionStyle.Cancel */, false);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
export function alert(arg) {
|
|
174
|
+
return new Promise((resolve, reject) => {
|
|
175
|
+
try {
|
|
176
|
+
const defaultOptions = {
|
|
177
|
+
okButtonText: DialogStrings.OK
|
|
178
|
+
};
|
|
179
|
+
const options = !isDialogOptions(arg) ? Object.assign(defaultOptions, { message: arg + '' }) : Object.assign(defaultOptions, arg);
|
|
180
|
+
const alertController = createAlertController(options, resolve);
|
|
181
|
+
addButtonsToAlertController(alertController, options, (result) => {
|
|
182
|
+
resolve(result);
|
|
183
|
+
});
|
|
184
|
+
showUIAlertController(alertController, options);
|
|
185
|
+
}
|
|
186
|
+
catch (ex) {
|
|
187
|
+
reject(ex);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
export class AlertDialog {
|
|
192
|
+
constructor(options) {
|
|
193
|
+
this.options = options;
|
|
194
|
+
this.hiding = false;
|
|
195
|
+
}
|
|
196
|
+
show(onClosed) {
|
|
197
|
+
if (!this.alertController) {
|
|
198
|
+
this.alertController = createAlertController(this.options, onClosed);
|
|
199
|
+
this.presentingController = showUIAlertController(this.alertController, this.options);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async hide(result) {
|
|
203
|
+
if (this.presentingController && !this.hiding) {
|
|
204
|
+
this.hiding = true;
|
|
205
|
+
return new Promise((resolve) => {
|
|
206
|
+
this.alertController.dismissViewControllerAnimatedCompletion(true, () => {
|
|
207
|
+
if (this.alertController._resolveFunction) {
|
|
208
|
+
this.alertController._resolveFunction(result);
|
|
209
|
+
this.alertController._resolveFunction = null;
|
|
210
|
+
}
|
|
211
|
+
resolve?.();
|
|
212
|
+
this.alertController.clear();
|
|
213
|
+
this.presentingController = null;
|
|
214
|
+
this.alertController = null;
|
|
215
|
+
this.hiding = false;
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
export function confirm(arg) {
|
|
222
|
+
return new Promise((resolve, reject) => {
|
|
223
|
+
try {
|
|
224
|
+
const defaultOptions = {
|
|
225
|
+
okButtonText: DialogStrings.OK,
|
|
226
|
+
cancelButtonText: DialogStrings.CANCEL
|
|
227
|
+
};
|
|
228
|
+
const options = !isDialogOptions(arg)
|
|
229
|
+
? Object.assign(defaultOptions, {
|
|
230
|
+
message: arg + ''
|
|
231
|
+
})
|
|
232
|
+
: Object.assign(defaultOptions, arg);
|
|
233
|
+
const alertController = createAlertController(options, resolve);
|
|
234
|
+
addButtonsToAlertController(alertController, options, (r) => {
|
|
235
|
+
resolve(r);
|
|
236
|
+
});
|
|
237
|
+
showUIAlertController(alertController, options);
|
|
238
|
+
}
|
|
239
|
+
catch (ex) {
|
|
240
|
+
reject(ex);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
function createTextField() {
|
|
245
|
+
const textField = new TextField();
|
|
246
|
+
// native text fields inside an alert get the system rounded border
|
|
247
|
+
textField.once('loaded', () => {
|
|
248
|
+
const nativeView = textField.nativeViewProtected;
|
|
249
|
+
if (nativeView) {
|
|
250
|
+
nativeView.borderStyle = 3 /* UITextBorderStyle.RoundedRect */;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
return textField;
|
|
254
|
+
}
|
|
255
|
+
export function prompt(...args) {
|
|
256
|
+
let options;
|
|
257
|
+
const defaultOptions = {
|
|
258
|
+
okButtonText: DialogStrings.OK,
|
|
259
|
+
cancelButtonText: DialogStrings.CANCEL,
|
|
260
|
+
inputType: inputType.text
|
|
261
|
+
};
|
|
262
|
+
if (args.length === 1) {
|
|
263
|
+
if (Utils.isString(args[0])) {
|
|
264
|
+
options = defaultOptions;
|
|
265
|
+
options.message = args[0];
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
options = Object.assign(defaultOptions, args[0]);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else if (args.length === 2) {
|
|
272
|
+
if (Utils.isString(args[0]) && Utils.isString(args[1])) {
|
|
273
|
+
options = defaultOptions;
|
|
274
|
+
options.message = args[0];
|
|
275
|
+
options.defaultText = args[1];
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return new Promise((resolve, reject) => {
|
|
279
|
+
try {
|
|
280
|
+
const stackLayout = options.stackViewHolder ?? new StackLayout();
|
|
281
|
+
if (options.messageView instanceof View) {
|
|
282
|
+
stackLayout.addChild(options.messageView);
|
|
283
|
+
}
|
|
284
|
+
const textField = createTextField();
|
|
285
|
+
textField.hint = options.hintText;
|
|
286
|
+
if (options.textFieldProperties) {
|
|
287
|
+
Object.assign(textField, options.textFieldProperties);
|
|
288
|
+
}
|
|
289
|
+
if (options.defaultText) {
|
|
290
|
+
textField.text = options.defaultText;
|
|
291
|
+
}
|
|
292
|
+
if (options.inputType === inputType.password) {
|
|
293
|
+
textField.secure = true;
|
|
294
|
+
}
|
|
295
|
+
else if (options.inputType === inputType.email) {
|
|
296
|
+
textField.keyboardType = 'email';
|
|
297
|
+
}
|
|
298
|
+
else if (options.inputType === inputType.number) {
|
|
299
|
+
textField.keyboardType = 'number';
|
|
300
|
+
}
|
|
301
|
+
else if (options.inputType === inputType.phone) {
|
|
302
|
+
textField.keyboardType = 'phone';
|
|
303
|
+
}
|
|
304
|
+
switch (options.capitalizationType) {
|
|
305
|
+
case capitalizationType.all: {
|
|
306
|
+
textField.autocapitalizationType = 'allcharacters';
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
case capitalizationType.sentences: {
|
|
310
|
+
textField.autocapitalizationType = 'sentences';
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
case capitalizationType.words: {
|
|
314
|
+
textField.autocapitalizationType = 'words';
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
stackLayout.addChild(textField);
|
|
319
|
+
if (options.view instanceof View) {
|
|
320
|
+
stackLayout.addChild(options.view);
|
|
321
|
+
}
|
|
322
|
+
options.view = stackLayout;
|
|
323
|
+
const alertController = createAlertController(options, resolve);
|
|
324
|
+
addButtonsToAlertController(alertController, options, (r) => {
|
|
325
|
+
alertController._resolveFunction = null;
|
|
326
|
+
resolve({ result: r, text: textField.text });
|
|
327
|
+
}, (r) => ({ result: r, text: textField.text }));
|
|
328
|
+
if (options.autoFocus) {
|
|
329
|
+
alertController.autoFocusTextField = textField;
|
|
330
|
+
}
|
|
331
|
+
showUIAlertController(alertController, options);
|
|
332
|
+
}
|
|
333
|
+
catch (ex) {
|
|
334
|
+
reject(ex);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
export function login(...args) {
|
|
339
|
+
let options;
|
|
340
|
+
const defaultOptions = {
|
|
341
|
+
okButtonText: DialogStrings.OK,
|
|
342
|
+
cancelButtonText: DialogStrings.CANCEL
|
|
343
|
+
};
|
|
344
|
+
if (args.length === 1) {
|
|
345
|
+
if (Utils.isString(args[0])) {
|
|
346
|
+
options = defaultOptions;
|
|
347
|
+
options.message = args[0];
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
options = Object.assign(defaultOptions, args[0]);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
else if (args.length === 2) {
|
|
354
|
+
if (Utils.isString(args[0]) && Utils.isString(args[1])) {
|
|
355
|
+
options = defaultOptions;
|
|
356
|
+
options.message = args[0];
|
|
357
|
+
options.userName = args[1];
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else if (args.length === 3) {
|
|
361
|
+
if (Utils.isString(args[0]) && Utils.isString(args[1]) && Utils.isString(args[2])) {
|
|
362
|
+
options = defaultOptions;
|
|
363
|
+
options.message = args[0];
|
|
364
|
+
options.userName = args[1];
|
|
365
|
+
options.password = args[2];
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return new Promise((resolve, reject) => {
|
|
369
|
+
try {
|
|
370
|
+
const stackLayout = options.stackViewHolder ?? new StackLayout();
|
|
371
|
+
if (options.messageView instanceof View) {
|
|
372
|
+
stackLayout.addChild(options.messageView);
|
|
373
|
+
}
|
|
374
|
+
const userNameTextField = createTextField();
|
|
375
|
+
userNameTextField.marginBottom = 10;
|
|
376
|
+
const passwordTextField = createTextField();
|
|
377
|
+
userNameTextField.hint = options.userNameHint || 'Username';
|
|
378
|
+
userNameTextField.text = options.userName;
|
|
379
|
+
passwordTextField.hint = options.passwordHint || 'Password';
|
|
380
|
+
passwordTextField.text = options.password;
|
|
381
|
+
passwordTextField.secure = true;
|
|
382
|
+
if (options.usernameTextFieldProperties) {
|
|
383
|
+
Object.assign(userNameTextField, options.usernameTextFieldProperties);
|
|
384
|
+
}
|
|
385
|
+
if (options.passwordTextFieldProperties) {
|
|
386
|
+
Object.assign(passwordTextField, options.passwordTextFieldProperties);
|
|
387
|
+
}
|
|
388
|
+
stackLayout.addChild(userNameTextField);
|
|
389
|
+
stackLayout.addChild(passwordTextField);
|
|
390
|
+
if (options.view instanceof View) {
|
|
391
|
+
stackLayout.addChild(options.view);
|
|
392
|
+
}
|
|
393
|
+
options.view = stackLayout;
|
|
394
|
+
const alertController = createAlertController(options, resolve);
|
|
395
|
+
addButtonsToAlertController(alertController, options, (r) => {
|
|
396
|
+
resolve({
|
|
397
|
+
result: r,
|
|
398
|
+
userName: userNameTextField.text,
|
|
399
|
+
password: passwordTextField.text
|
|
400
|
+
});
|
|
401
|
+
}, (r) => ({ result: r, userName: userNameTextField.text, password: passwordTextField.text }));
|
|
402
|
+
if (options.beforeShow) {
|
|
403
|
+
options.beforeShow(options, userNameTextField, passwordTextField);
|
|
404
|
+
}
|
|
405
|
+
if (options.autoFocus) {
|
|
406
|
+
alertController.autoFocusTextField = userNameTextField;
|
|
407
|
+
}
|
|
408
|
+
showUIAlertController(alertController, options);
|
|
409
|
+
}
|
|
410
|
+
catch (ex) {
|
|
411
|
+
reject(ex);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
function showUIAlertController(alertController, options) {
|
|
416
|
+
let rootView = Application.getRootView();
|
|
417
|
+
if (rootView.parent) {
|
|
418
|
+
rootView = rootView.parent;
|
|
419
|
+
}
|
|
420
|
+
let currentView = getCurrentPage() || rootView;
|
|
421
|
+
if (currentView) {
|
|
422
|
+
currentView = currentView.modal || currentView;
|
|
423
|
+
let viewController = currentView.viewController;
|
|
424
|
+
if (!viewController) {
|
|
425
|
+
throw new Error('no_controller_to_show_dialog');
|
|
426
|
+
}
|
|
427
|
+
// we check root modal view if there is no currently presented one or if the current one is an alert dialog without a child presented view
|
|
428
|
+
if ((!viewController.presentedViewController ||
|
|
429
|
+
(viewController.presentedViewController && viewController.presentedViewController['isAlertController'] && !viewController.presentedViewController.presentedViewController)) &&
|
|
430
|
+
rootView.viewController.presentedViewController &&
|
|
431
|
+
!rootView.viewController.presentedViewController.beingDismissed) {
|
|
432
|
+
viewController = rootView.viewController.presentedViewController;
|
|
433
|
+
}
|
|
434
|
+
while (viewController.presentedViewController && !viewController.presentedViewController.beingDismissed) {
|
|
435
|
+
while (viewController.presentedViewController instanceof UIAlertController ||
|
|
436
|
+
(viewController.presentedViewController['isAlertController'] && viewController.presentedViewController.presentedViewController)) {
|
|
437
|
+
viewController = viewController.presentedViewController;
|
|
438
|
+
}
|
|
439
|
+
if (viewController.presentedViewController instanceof UIAlertController || viewController.presentedViewController['isAlertController']) {
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
viewController = viewController.presentedViewController;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
if (showingDialogs.indexOf(alertController) === -1) {
|
|
447
|
+
showingDialogs.push(alertController);
|
|
448
|
+
}
|
|
449
|
+
function block() {
|
|
450
|
+
if (alertController.popoverPresentationController) {
|
|
451
|
+
alertController.popoverPresentationController.sourceView = viewController.view;
|
|
452
|
+
alertController.popoverPresentationController.sourceRect = CGRectMake(viewController.view.bounds.size.width / 2.0, viewController.view.bounds.size.height / 2.0, 1.0, 1.0);
|
|
453
|
+
alertController.popoverPresentationController.permittedArrowDirections = 0;
|
|
454
|
+
}
|
|
455
|
+
viewController.presentViewControllerAnimatedCompletion(alertController, true, () => {
|
|
456
|
+
if (alertController.autoFocusTextField) {
|
|
457
|
+
alertController.autoFocusTextField.requestFocus();
|
|
458
|
+
alertController.autoFocusTextField = null;
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
if (viewController.presentedViewController) {
|
|
463
|
+
if (viewController.presentedViewController.beingDismissed || options.iosForceClosePresentedViewController === true) {
|
|
464
|
+
viewController.dismissViewControllerAnimatedCompletion(true, () => {
|
|
465
|
+
block();
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
throw new Error('controller_already_presented');
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
block();
|
|
474
|
+
}
|
|
475
|
+
return viewController;
|
|
476
|
+
}
|
|
477
|
+
throw new Error('no_controller_to_show_dialog');
|
|
478
|
+
}
|
|
479
|
+
export function action(...args) {
|
|
480
|
+
let options;
|
|
481
|
+
const defaultOptions = {
|
|
482
|
+
cancelButtonText: DialogStrings.CANCEL
|
|
483
|
+
};
|
|
484
|
+
if (args.length === 1) {
|
|
485
|
+
if (Utils.isString(args[0])) {
|
|
486
|
+
options = defaultOptions;
|
|
487
|
+
options.message = args[0];
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
options = Object.assign(defaultOptions, args[0]);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
else if (args.length === 2) {
|
|
494
|
+
if (Utils.isString(args[0]) && Utils.isString(args[1])) {
|
|
495
|
+
options = defaultOptions;
|
|
496
|
+
options.message = args[0];
|
|
497
|
+
options.cancelButtonText = args[1];
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
else if (args.length === 3) {
|
|
501
|
+
if (Utils.isString(args[0]) && Utils.isString(args[1]) && Utils.isDefined(args[2])) {
|
|
502
|
+
options = defaultOptions;
|
|
503
|
+
options.message = args[0];
|
|
504
|
+
options.cancelButtonText = args[1];
|
|
505
|
+
options.actions = args[2];
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return new Promise((resolve, reject) => {
|
|
509
|
+
try {
|
|
510
|
+
// an action sheet is the native pattern to choose between actions
|
|
511
|
+
const alertController = createAlertController(options, resolve, 0 /* UIAlertControllerStyle.ActionSheet */);
|
|
512
|
+
if (options.actions) {
|
|
513
|
+
for (const action of options.actions) {
|
|
514
|
+
if (Utils.isString(action)) {
|
|
515
|
+
alertController.addAction(UIAlertAction.actionWithTitleStyleHandler(action, 0 /* UIAlertActionStyle.Default */, (arg) => {
|
|
516
|
+
alertController.clear();
|
|
517
|
+
resolve(arg.title);
|
|
518
|
+
}));
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
if (Utils.isString(options.cancelButtonText)) {
|
|
523
|
+
alertController.addAction(UIAlertAction.actionWithTitleStyleHandler(options.cancelButtonText, 1 /* UIAlertActionStyle.Cancel */, (arg) => {
|
|
524
|
+
alertController.clear();
|
|
525
|
+
resolve(arg.title);
|
|
526
|
+
}));
|
|
527
|
+
}
|
|
528
|
+
showUIAlertController(alertController, options);
|
|
529
|
+
}
|
|
530
|
+
catch (ex) {
|
|
531
|
+
reject(ex);
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
//# sourceMappingURL=index.ios.js.map
|