Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to add handlers for prompts #230

Open
angelobreuer opened this issue Jan 14, 2021 · 5 comments
Open

Allow to add handlers for prompts #230

angelobreuer opened this issue Jan 14, 2021 · 5 comments
Labels
feature ⭐ top feature Top feature request. ⭐ top issue Top issue.

Comments

@angelobreuer
Copy link

angelobreuer commented Jan 14, 2021

Is your feature request related to a problem? Please describe.
Allow users to add hooks to prompts.

Describe the solution you'd like
For example, adding the support of doing the following:

using System.Collections.Generic;
using System.Linq;
using Spectre.Console;

void Update(IReadOnlyList<int> items, PromptAction action)
{
    var bits = items.Aggregate(seed: 0, (a, b) => a | b);

    AnsiConsole.Cursor.SetPosition(20, 1);
    AnsiConsole.WriteLine($"Bits set: {bits:X8}");
}

var prompt = new MultiSelectionPrompt<int>()
    .Handler((list, action) => Update(list));

internal enum PromptAction : byte
{
    ItemSelected,
    ItemDeselected,

    // ..
}

Why is this needed?
I think adding hooks would be helpful to inform the user about what is set.

This would also add the ability to make something like the following:

using System;
using System.Collections.Generic;
using Spectre.Console;

void Update(IReadOnlyList<Item> items, PromptAction action)
{
    if (action is PromptAction.ItemSelected)
    {
        AnsiConsole.Cursor.SetPosition(20, 1);
        AnsiConsole.WriteLine(items[items.Count - 1].Description);
    }
}

var prompt = new SelectionPrompt<int>()
    .Handler((list, action) => Update(list));

internal enum PromptAction : byte
{
    ItemSelected,
    ItemDeselected,

    // ..
}

internal class Item
{
    public Item(string name, string description)
    {
        Name = name ?? throw new ArgumentNullException(nameof(name));
        Description = description ?? throw new ArgumentNullException(nameof(description));
    }

    public string Name { get; }

    public string Description { get; }
}

Describe alternatives you've considered
---

Additional context
I would be able to grab this if this is considered a feature.


Please upvote 👍 this issue if you are interested in it.

@patriksvensson
Copy link
Contributor

@angelobreuer I'm having a difficult time seeing how this would bring any big benefits.
What is the use case of this? Is it to display contextual information about items in the list?

@angelobreuer
Copy link
Author

-- @patriksvensson
Thank you very much for your response.

What is the use case of this? Is it to display contextual information about items in the list?

Yes, in my project, I have some cases where live, interactive prompts could benefit the user experience.

For example, I have a multi-selection prompt, where I allow the user to select bit flags. For instance, I would explain (on the right in the console) what the bit flag is supposed for and what bit mask is currently calculated.

Additionally, I also have another use case: I provide a tui to run examples that demonstrate my library's use. These samples are selectable using the selection prompt. Adding handlers would make me able to give a description based on the sample metadata. (Maybe off-topic: Another idea that came up is to provide the user with information about the sample was to have a table where on the left is a selection prompt and on the right the description of the sample. I suddenly did not find a solution for using spectre. As a) the interactive selection handling is missing and b) tables with a prompt is currently, as far I know, not directly supported).

Generally, I think prompts are a handy "thing," but they do not provide much flexibility as they take something in and out without allowing any attachable interrupts. This would provide developers way more flexibility when working with prompts.

Another use case would be to allow developers to preload things as the user scrolls down (which would expand the issue itself because I think this may require some structural changes). In my "sample runner", I have the user select an environment where to try out that sample, the list of environments may be small, but also large, the data amount is unknown, and the API allows only to request the data in chunks. Hence, the prompt is very limited in this case, as only fixed data is allowed.

Thank you for reading!

@Blackclaws
Copy link

This is actually a rather useful feature to have in multiselect prompts where selecting one item selects others as they might be dependencies.

I'm currently using this to write a development kit console application where selecting dependencies as locked multiselect items that you can't unlock until the parent is also deselected would be nice to have.

Since dependencies show up multiple times you can't just group it once but would have to instead group it multiple times.

@MaxAtoms
Copy link
Contributor

Yesterday, I came up with the same idea as @angelobreuer. I have seen similar TUI approaches in Telescope (https://github.com/nvim-telescope/telescope.nvim) and fzf (https://github.com/junegunn/fzf). These tools can show previews for each selection in a right-hand side panel.

While digging through the code and documentation, I realized that adding hooks for handlers would probably be fairly easy to do. I think the harder part which would require more design work, is the other side of the hook. How would the handler affect rendering of other components? Currently, there is only the Live Display that allows to update widgets.

@cnayan
Copy link

cnayan commented Mar 14, 2024

My view on this requirement-

I have a dependency of items on each other. Say, if I have A, B and C listed, selecting B, should also select A immediately.
This is not possible without a handler, or extending the MultiSelectionPrompt which has been sealed.

I also could not provide my own IListPromptStrategy<T> instance, because the interface is internal. If it was accessible and allowed to be attached to the prompt, I could have handled the input events. If I could receive events, I could toggle the IsSelected property of IMultiSelectionItem<T> interface and possibly have the desired impact.

On the other hand, if I want to make it look like a tree selection in prompt, (not sure if it is supported even), I can't AddChoice of IMultiSelectionItem<T> because it is not supported, even though IMultiSelectionItem<T> can have a child node added!

There are lot of design restrictions that should be reviewed.

@github-actions github-actions bot added ⭐ top issue Top issue. ⭐ top feature Top feature request. labels Apr 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature ⭐ top feature Top feature request. ⭐ top issue Top issue.
Projects
Status: No status
Development

No branches or pull requests

5 participants