UNPKG

12.3 kBJavaScriptView Raw
1// Copyright (c) Jupyter Development Team.
2// Distributed under the terms of the Modified BSD License.
3import { Widget } from '@lumino/widgets';
4import { Dialog, showDialog } from './dialog';
5const INPUT_DIALOG_CLASS = 'jp-Input-Dialog';
6const INPUT_BOOLEAN_DIALOG_CLASS = 'jp-Input-Boolean-Dialog';
7/**
8 * Namespace for input dialogs
9 */
10export var InputDialog;
11(function (InputDialog) {
12 /**
13 * Create and show a input dialog for a boolean.
14 *
15 * @param options - The dialog setup options.
16 *
17 * @returns A promise that resolves with whether the dialog was accepted
18 */
19 function getBoolean(options) {
20 return showDialog({
21 ...options,
22 body: new InputBooleanDialog(options),
23 buttons: [
24 Dialog.cancelButton({ label: options.cancelLabel }),
25 Dialog.okButton({ label: options.okLabel })
26 ],
27 focusNodeSelector: 'input'
28 });
29 }
30 InputDialog.getBoolean = getBoolean;
31 /**
32 * Create and show a input dialog for a number.
33 *
34 * @param options - The dialog setup options.
35 *
36 * @returns A promise that resolves with whether the dialog was accepted
37 */
38 function getNumber(options) {
39 return showDialog({
40 ...options,
41 body: new InputNumberDialog(options),
42 buttons: [
43 Dialog.cancelButton({ label: options.cancelLabel }),
44 Dialog.okButton({ label: options.okLabel })
45 ],
46 focusNodeSelector: 'input'
47 });
48 }
49 InputDialog.getNumber = getNumber;
50 /**
51 * Create and show a input dialog for a choice.
52 *
53 * @param options - The dialog setup options.
54 *
55 * @returns A promise that resolves with whether the dialog was accepted
56 */
57 function getItem(options) {
58 return showDialog({
59 ...options,
60 body: new InputItemsDialog(options),
61 buttons: [
62 Dialog.cancelButton({ label: options.cancelLabel }),
63 Dialog.okButton({ label: options.okLabel })
64 ],
65 focusNodeSelector: options.editable ? 'input' : 'select'
66 });
67 }
68 InputDialog.getItem = getItem;
69 /**
70 * Create and show a input dialog for a choice.
71 *
72 * @param options - The dialog setup options.
73 *
74 * @returns A promise that resolves with whether the dialog was accepted
75 */
76 function getMultipleItems(options) {
77 return showDialog({
78 ...options,
79 body: new InputMultipleItemsDialog(options),
80 buttons: [
81 Dialog.cancelButton({ label: options.cancelLabel }),
82 Dialog.okButton({ label: options.okLabel })
83 ]
84 });
85 }
86 InputDialog.getMultipleItems = getMultipleItems;
87 /**
88 * Create and show a input dialog for a text.
89 *
90 * @param options - The dialog setup options.
91 *
92 * @returns A promise that resolves with whether the dialog was accepted
93 */
94 function getText(options) {
95 return showDialog({
96 ...options,
97 body: new InputTextDialog(options),
98 buttons: [
99 Dialog.cancelButton({ label: options.cancelLabel }),
100 Dialog.okButton({ label: options.okLabel })
101 ],
102 focusNodeSelector: 'input'
103 });
104 }
105 InputDialog.getText = getText;
106 /**
107 * Create and show a input dialog for a password.
108 *
109 * @param options - The dialog setup options.
110 *
111 * @returns A promise that resolves with whether the dialog was accepted
112 */
113 function getPassword(options) {
114 return showDialog({
115 ...options,
116 body: new InputPasswordDialog(options),
117 buttons: [
118 Dialog.cancelButton({ label: options.cancelLabel }),
119 Dialog.okButton({ label: options.okLabel })
120 ],
121 focusNodeSelector: 'input'
122 });
123 }
124 InputDialog.getPassword = getPassword;
125})(InputDialog || (InputDialog = {}));
126/**
127 * Base widget for input dialog body
128 */
129class InputDialogBase extends Widget {
130 /**
131 * InputDialog constructor
132 *
133 * @param label Input field label
134 */
135 constructor(options) {
136 super();
137 this.addClass(INPUT_DIALOG_CLASS);
138 this._input = document.createElement('input');
139 this._input.classList.add('jp-mod-styled');
140 this._input.id = 'jp-dialog-input-id';
141 if (options.label !== undefined) {
142 const labelElement = document.createElement('label');
143 labelElement.textContent = options.label;
144 labelElement.htmlFor = this._input.id;
145 // Initialize the node
146 this.node.appendChild(labelElement);
147 }
148 const wrapper = document.createElement('div');
149 wrapper.className = 'jp-InputDialog-inputWrapper';
150 if (options.prefix) {
151 const prefix = document.createElement('span');
152 prefix.className = 'jp-InputDialog-inputPrefix';
153 prefix.textContent = options.prefix;
154 // Both US WDS (https://designsystem.digital.gov/components/input-prefix-suffix/)
155 // and UK DS (https://design-system.service.gov.uk/components/text-input/) recommend
156 // hiding prefixes and suffixes from screen readers.
157 prefix.ariaHidden = 'true';
158 wrapper.appendChild(prefix);
159 }
160 wrapper.appendChild(this._input);
161 if (options.suffix) {
162 const suffix = document.createElement('span');
163 suffix.className = 'jp-InputDialog-inputSuffix';
164 suffix.textContent = options.suffix;
165 suffix.ariaHidden = 'true';
166 wrapper.appendChild(suffix);
167 }
168 this.node.appendChild(wrapper);
169 }
170}
171/**
172 * Widget body for input boolean dialog
173 */
174class InputBooleanDialog extends InputDialogBase {
175 /**
176 * InputBooleanDialog constructor
177 *
178 * @param options Constructor options
179 */
180 constructor(options) {
181 super(options);
182 this.addClass(INPUT_BOOLEAN_DIALOG_CLASS);
183 this._input.type = 'checkbox';
184 this._input.checked = options.value ? true : false;
185 }
186 /**
187 * Get the text specified by the user
188 */
189 getValue() {
190 return this._input.checked;
191 }
192}
193/**
194 * Widget body for input number dialog
195 */
196class InputNumberDialog extends InputDialogBase {
197 /**
198 * InputNumberDialog constructor
199 *
200 * @param options Constructor options
201 */
202 constructor(options) {
203 super(options);
204 this._input.type = 'number';
205 this._input.value = options.value ? options.value.toString() : '0';
206 }
207 /**
208 * Get the number specified by the user.
209 */
210 getValue() {
211 if (this._input.value) {
212 return Number(this._input.value);
213 }
214 else {
215 return Number.NaN;
216 }
217 }
218}
219/**
220 * Base widget body for input text/password/email dialog
221 */
222class InputDialogTextBase extends InputDialogBase {
223 /**
224 * InputDialogTextBase constructor
225 *
226 * @param options Constructor options
227 */
228 constructor(options) {
229 super(options);
230 this._input.value = options.text ? options.text : '';
231 if (options.placeholder) {
232 this._input.placeholder = options.placeholder;
233 }
234 if (options.pattern) {
235 this._input.pattern = options.pattern;
236 }
237 if (options.required) {
238 this._input.required = options.required;
239 }
240 }
241 /**
242 * Get the text specified by the user
243 */
244 getValue() {
245 return this._input.value;
246 }
247}
248/**
249 * Widget body for input text dialog
250 */
251class InputTextDialog extends InputDialogTextBase {
252 /**
253 * InputTextDialog constructor
254 *
255 * @param options Constructor options
256 */
257 constructor(options) {
258 var _a;
259 super(options);
260 this._input.type = 'text';
261 this._initialSelectionRange = Math.min(this._input.value.length, Math.max(0, (_a = options.selectionRange) !== null && _a !== void 0 ? _a : this._input.value.length));
262 }
263 /**
264 * A message handler invoked on an `'after-attach'` message.
265 */
266 onAfterAttach(msg) {
267 super.onAfterAttach(msg);
268 if (this._initialSelectionRange > 0 && this._input.value) {
269 this._input.setSelectionRange(0, this._initialSelectionRange);
270 }
271 }
272}
273/**
274 * Widget body for input password dialog
275 */
276class InputPasswordDialog extends InputDialogTextBase {
277 /**
278 * InputPasswordDialog constructor
279 *
280 * @param options Constructor options
281 */
282 constructor(options) {
283 super(options);
284 this._input.type = 'password';
285 }
286 /**
287 * A message handler invoked on an `'after-attach'` message.
288 */
289 onAfterAttach(msg) {
290 super.onAfterAttach(msg);
291 if (this._input.value) {
292 this._input.select();
293 }
294 }
295}
296/**
297 * Widget body for input list dialog
298 */
299class InputItemsDialog extends InputDialogBase {
300 /**
301 * InputItemsDialog constructor
302 *
303 * @param options Constructor options
304 */
305 constructor(options) {
306 super(options);
307 this._editable = options.editable || false;
308 let current = options.current || 0;
309 let defaultIndex;
310 if (typeof current === 'number') {
311 defaultIndex = Math.max(0, Math.min(current, options.items.length - 1));
312 current = '';
313 }
314 this._list = document.createElement('select');
315 options.items.forEach((item, index) => {
316 const option = document.createElement('option');
317 if (index === defaultIndex) {
318 option.selected = true;
319 current = item;
320 }
321 option.value = item;
322 option.textContent = item;
323 this._list.appendChild(option);
324 });
325 if (options.editable) {
326 /* Use of list and datalist */
327 const data = document.createElement('datalist');
328 data.id = 'input-dialog-items';
329 data.appendChild(this._list);
330 this._input.type = 'list';
331 this._input.value = current;
332 this._input.setAttribute('list', data.id);
333 if (options.placeholder) {
334 this._input.placeholder = options.placeholder;
335 }
336 this.node.appendChild(data);
337 }
338 else {
339 /* Use select directly */
340 this._input.parentElement.replaceChild(this._list, this._input);
341 }
342 }
343 /**
344 * Get the user choice
345 */
346 getValue() {
347 if (this._editable) {
348 return this._input.value;
349 }
350 else {
351 return this._list.value;
352 }
353 }
354}
355/**
356 * Widget body for input list dialog
357 */
358class InputMultipleItemsDialog extends InputDialogBase {
359 /**
360 * InputMultipleItemsDialog constructor
361 *
362 * @param options Constructor options
363 */
364 constructor(options) {
365 super(options);
366 let defaults = options.defaults || [];
367 this._list = document.createElement('select');
368 this._list.setAttribute('multiple', '');
369 options.items.forEach(item => {
370 const option = document.createElement('option');
371 option.value = item;
372 option.textContent = item;
373 this._list.appendChild(option);
374 });
375 // use the select
376 this._input.remove();
377 this.node.appendChild(this._list);
378 // select the current ones
379 const htmlOptions = this._list.options;
380 for (let i = 0; i < htmlOptions.length; i++) {
381 const option = htmlOptions[i];
382 if (defaults.includes(option.value)) {
383 option.selected = true;
384 }
385 else {
386 option.selected = false;
387 }
388 }
389 }
390 /**
391 * Get the user choices
392 */
393 getValue() {
394 let result = [];
395 for (let opt of this._list.options) {
396 if (opt.selected && !opt.classList.contains('hidden')) {
397 result.push(opt.value || opt.text);
398 }
399 }
400 return result;
401 }
402}
403//# sourceMappingURL=inputdialog.js.map
\No newline at end of file