UNPKG

neo-neo-bblessed

Version:

A fork of neo-blessed (which is a fork of blessed) with bug fixes and maintenance.

192 lines (162 loc) 4.04 kB
/** * question.js - question element for blessed * Copyright (c) 2013-2015, Christopher Jeffrey and contributors (MIT License). * https://github.com/chjj/blessed */ /** * Modules */ import Node from './node.js'; import boxFactory from './box.js'; const Box = boxFactory.Box; import buttonFactory from './button.js'; const Button = buttonFactory.Button; /** * Type definitions */ interface QuestionOptions { hidden?: boolean; [key: string]: any; } interface QuestionKey { name: string; } interface QuestionScreen { saveFocus(): void; restoreFocus(): void; render(): void; } interface QuestionButton { on(event: string, listener: () => void): void; removeListener(event: string, listener: () => void): void; } interface QuestionInterface extends Box { type: string; screen: QuestionScreen; _: { okay: QuestionButton; cancel: QuestionButton; }; show(): void; hide(): void; focus(): void; setContent(text: string): void; onScreenEvent(event: string, listener: (...args: any[]) => void): void; removeScreenEvent(event: string, listener: (...args: any[]) => void): void; ask(text: string, callback: (err: any, data: boolean) => void): void; } /** * Question - Modern ES6 Class */ class Question extends Box { type = 'question'; _: { okay: QuestionButton; cancel: QuestionButton; }; constructor(options?: QuestionOptions) { // Handle malformed options gracefully if (!options || typeof options !== 'object' || Array.isArray(options)) { options = {}; } // Set default hidden behavior for questions options.hidden = true; super(options); // Initialize the internal button container this._ = {} as any; // Create OK button this._.okay = new Button({ screen: this.screen, parent: this, top: 2, height: 1, left: 2, width: 6, content: 'Okay', align: 'center', bg: 'black', hoverBg: 'blue', autoFocus: false, mouse: true, }); // Create Cancel button this._.cancel = new Button({ screen: this.screen, parent: this, top: 2, height: 1, shrink: true, left: 10, width: 8, content: 'Cancel', align: 'center', bg: 'black', hoverBg: 'blue', autoFocus: false, mouse: true, }); } ask(text: string, callback: (err: any, data: boolean) => void): void { const self = this; let press: (ch: string, key: QuestionKey) => void; let okay: () => void; let cancel: () => void; // Keep above: // var parent = this.parent; // this.detach(); // parent.append(this); this.show(); this.setContent(' ' + text); this.onScreenEvent( 'keypress', (press = function (ch: string, key: QuestionKey) { if (key.name === 'mouse') return; if ( key.name !== 'enter' && key.name !== 'escape' && key.name !== 'q' && key.name !== 'y' && key.name !== 'n' ) { return; } done(null, key.name === 'enter' || key.name === 'y'); }) ); this._.okay.on( 'press', (okay = function () { done(null, true); }) ); this._.cancel.on( 'press', (cancel = function () { done(null, false); }) ); this.screen.saveFocus(); this.focus(); function done(err: any, data: boolean) { self.hide(); self.screen.restoreFocus(); self.removeScreenEvent('keypress', press); self._.okay.removeListener('press', okay); self._.cancel.removeListener('press', cancel); return callback(err, data); } this.screen.render(); } } /** * Factory function for backward compatibility */ function question(options?: QuestionOptions): QuestionInterface { return new Question(options) as QuestionInterface; } // Attach the class as a property for direct access question.Question = Question; /** * Expose */ export default question;