Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blessed "Prompt" is black on black by default - how do I style it?

I am using blessed and I am trying to add a prompt to my application. It works fine, but I can't read its text. I have prepared a minimal example, that illustrates, what I see.

I would like to know how I can style the text in the inputs. The style-Attributes as mentioned in the docs seem to have no effect.

Here's what I see (there is text in the input and on the two buttons, but it is black on black).

enter image description here

Here's code that reproduces the error on Debian 9 with standard terminal and standard theme:

var blessed = require('blessed');
var screen = blessed.screen({});

var prompt = blessed.prompt({
    left: 'center',
    top: 'center',
    height: 'shrink',
    width: 'shrink',
    border: 'line',
});

screen.append(prompt);

screen.key(['q', 'C-c'], function quit() {
    return process.exit(0);
});

screen.render();

prompt.input('Search:', 'test', function() {});
like image 550
amenthes Avatar asked Oct 29 '22 02:10

amenthes


1 Answers

Disclaimer: I'm not very familiar with the blessed codebase, so there might be a more native way of doing this. If there isn't, then it sounds like this feature should be requested / implemented.

Observation 1 - Your terminal's color settings are contributing to the problem

Based on the screenshot you gave, your terminal's default colors have a black foreground against a white background. If you invert this in your terminal settings, you should be able to see the expected behavior.

But! Your application should no matter what the user's settings are, so that isn't a good solution...

Observation 2 - The Prompt constructor hardcodes it's children with a black background

When in doubt, go to the source! Here is part of prompt.js as of 2017-09-30:

// ...
function Prompt(options) {
  // ...
  Box.call(this, options);

  this._.input = new Textbox({
    // ...
    bg: 'black'
  });

  this._.okay = new Button({
    // ...
    bg: 'black',
    hoverBg: 'blue',
  });

  this._.cancel = new Button({
    // ...
    bg: 'black',
    hoverBg: 'blue',
  });
}
// ...

So, it seems like the only way to fix your issue is to overwrite these children's style properties after the Prompt has been created.

Solution 1 - Overwrite child style properties after creation

After you create the prompt, you can overwrite the style of each child. It's probably most straightforward to just make the foreground white (as it should be)...

Also, for maintainability's sake, this hack really should be in it's own function.

function createBlessedPrompt(options) {
    var prompt = blessed.prompt(options);

    // NOTE - Not sure if blessed has some sortof `children()` selector.
    //        If not, we probably should create one.
    //        Nevertheless, temporarily hardcoding the children here...
    //
    var promptChildren = [prompt._.input, prompt._.okay, prompt._.cancel];

    promptChildren.forEach(x => {
        Object.assign(x.style, {
            fg: 'white',
            bg: 'black'
        });
    });

    return prompt;
}

Solution 2 - Submit a bug fix to the blessed repository

This really seems like an issue with blessed itself. If you can think of a way that Prompt should properly handle this case, you should totally help your fellow coder and write an issue / pull request that fixes this.

Good luck!

like image 188
souldzin Avatar answered Nov 11 '22 21:11

souldzin