123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- import { Widget } from '@phosphor/widgets';
- import { Dialog } from './dialog';
- import { Styling } from './styling';
- const INPUT_DIALOG_CLASS = 'jp-Input-Dialog';
- /**
- * Create and show a input dialog for a number.
- *
- * @param options - The dialog setup options.
- *
- * @returns A promise that resolves with whether the dialog was accepted
- */
- export function getNumber(
- options: InputDialog.INumberOptions
- ): Promise<Dialog.IResult<number>> {
- let dialog = new Dialog({
- ...options,
- body: new InputNumberDialog(options)
- });
- return dialog.launch();
- }
- /**
- * Create and show a input dialog for a choice.
- *
- * @param options - The dialog setup options.
- *
- * @returns A promise that resolves with whether the dialog was accepted
- */
- export function getItem(
- options: InputDialog.IItemOptions
- ): Promise<Dialog.IResult<string>> {
- let dialog = new Dialog({
- ...options,
- body: new InputItemsDialog(options)
- });
- return dialog.launch();
- }
- /**
- * Create and show a input dialog for a text.
- *
- * @param options - The dialog setup options.
- *
- * @returns A promise that resolves with whether the dialog was accepted
- */
- export function getText(
- options: InputDialog.ITextOptions
- ): Promise<Dialog.IResult<string>> {
- let dialog = new Dialog({
- ...options,
- body: new InputTextDialog(options)
- });
- return dialog.launch();
- }
- export namespace InputDialog {
- export interface IOptions<T>
- extends Partial<
- Pick<
- Dialog.IOptions<T>,
- Exclude<keyof Dialog.IOptions<T>, 'body' | 'buttons' | 'defaultButton'>
- >
- > {
- /**
- * Label of the requested input
- */
- label: string;
- }
- export interface INumberOptions extends IOptions<Number> {
- /**
- * Default value
- */
- value?: number;
- }
- export interface IItemOptions extends IOptions<string> {
- /**
- * List of choices
- */
- items: Array<string>;
- /**
- * Default choice
- *
- * If the list is editable a string with a default value can be provided
- * otherwise the index of the default choice should be given.
- */
- current?: number | string;
- /**
- * Is the item editable?
- */
- editable?: boolean;
- /**
- * Placeholder text for editable input
- */
- placeholder?: string;
- }
- export interface ITextOptions extends IOptions<string> {
- /**
- * Default input text
- */
- text?: string;
- /**
- * Placeholder text
- */
- placeholder?: string;
- }
- }
- /**
- * Base widget for input dialog body
- */
- class InputDialog<T> extends Widget implements Dialog.IBodyWidget<T> {
- /**
- * InputDialog constructor
- *
- * @param label Input field label
- */
- constructor(label: string) {
- super();
- this.addClass(INPUT_DIALOG_CLASS);
- let labelElement = document.createElement('label');
- labelElement.textContent = label;
- // Initialize the node
- this.node.appendChild(labelElement);
- }
- /** Input HTML node */
- protected _input: HTMLInputElement;
- }
- /**
- * Widget body for input number dialog
- */
- class InputNumberDialog extends InputDialog<number> {
- /**
- * InputNumberDialog constructor
- *
- * @param options Constructor options
- */
- constructor(options: InputDialog.INumberOptions) {
- super(options.label);
- this._input = document.createElement('input', {});
- this._input.classList.add('jp-mod-styled');
- this._input.type = 'number';
- this._input.value = options.value ? options.value.toString() : '0';
- // Initialize the node
- this.node.appendChild(this._input);
- }
- /**
- * Get the number specified by the user.
- */
- getValue(): number {
- if (this._input.value) {
- return Number(this._input.value);
- } else {
- return Number.NaN;
- }
- }
- }
- /**
- * Widget body for input text dialog
- */
- class InputTextDialog extends InputDialog<string> {
- /**
- * InputTextDialog constructor
- *
- * @param options Constructor options
- */
- constructor(options: InputDialog.ITextOptions) {
- super(options.label);
- this._input = document.createElement('input', {});
- this._input.classList.add('jp-mod-styled');
- this._input.type = 'text';
- this._input.value = options.text ? options.text : '';
- if (options.placeholder) {
- this._input.placeholder = options.placeholder;
- }
- // Initialize the node
- this.node.appendChild(this._input);
- }
- /**
- * Get the text specified by the user
- */
- getValue(): string {
- return this._input.value;
- }
- }
- /**
- * Widget body for input list dialog
- */
- class InputItemsDialog extends InputDialog<string> {
- /**
- * InputItemsDialog constructor
- *
- * @param options Constructor options
- */
- constructor(options: InputDialog.IItemOptions) {
- super(options.label);
- this._editable = options.editable || false;
- let current = options.current || 0;
- let defaultIndex: number;
- if (typeof current === 'number') {
- defaultIndex = Math.max(0, Math.min(current, options.items.length - 1));
- current = '';
- }
- this._list = document.createElement('select');
- options.items.forEach((item, index) => {
- let option = document.createElement('option');
- if (index === defaultIndex) {
- option.selected = true;
- current = item;
- }
- option.value = item;
- option.textContent = item;
- this._list.appendChild(option);
- });
- if (options.editable) {
- /* Use of list and datalist */
- let data = document.createElement('datalist');
- data.id = 'input-dialog-items';
- data.appendChild(this._list);
- this._input = document.createElement('input', {});
- this._input.classList.add('jp-mod-styled');
- this._input.type = 'list';
- this._input.value = current;
- this._input.setAttribute('list', data.id);
- if (options.placeholder) {
- this._input.placeholder = options.placeholder;
- }
- this.node.appendChild(this._input);
- this.node.appendChild(data);
- } else {
- /* Use select directly */
- this.node.appendChild(Styling.wrapSelect(this._list));
- }
- }
- /**
- * Get the user choice
- */
- getValue(): string {
- if (this._editable) {
- return this._input.value;
- } else {
- return this._list.value;
- }
- }
- private _list: HTMLSelectElement;
- private _editable: boolean;
- }
|