Skip to content

Grouped items #217

Open
Open
@jtreminio

Description

SplitItem radio works well:

<?php

use PhpSchool\CliMenu\Builder\SplitItemBuilder;
use PhpSchool\CliMenu\CliMenu;
use PhpSchool\CliMenu\Builder\CliMenuBuilder;

require_once(__DIR__ . '/../vendor/autoload.php');

$menu = (new CliMenuBuilder)
    ->setTitle('Header 1')
    ->addSplitItem(function (SplitItemBuilder $b) use ($itemCallable) {
        $b->addRadioItem('Item 1-A', function() {})
            ->addRadioItem('Item 1-B', function() {})
            ->addRadioItem('Item 1-C', function() {})
        ;
    })
    ->build();

$menu->open();

But it's not possible to have multiple groups of RadioItem within the same menu level:

$menu = (new CliMenuBuilder)
    ->addStaticItem('Header 1')
    ->addRadioItem('Item 1-A', function() {})
    ->addRadioItem('Item 1-B', function() {})
    ->addRadioItem('Item 1-C', function() {})
    ->addLineBreak('---')
    ->addStaticItem('Header 2')
    ->addRadioItem('Item 2-A', function() {})
    ->addRadioItem('Item 2-B', function() {})
    ->addRadioItem('Item 2-C', function() {})
    ->build();

$menu->open();

Peek 2019-12-20 19-15

Similarly, I want to be able to group non-RadioItem items together.

I'm thinking a non-styled container item that can take any number of MenuItemInterface items.

It has the following API:

  • addItem()
  • addItems()
  • setItems()
  • removeItem()

If it contains no items, the parent CliMenu displays nothing - it is only a container of items and has no styling of its own, nor does it affect the UI.

If it has items, it behaves as if those items were defined in-line with the parent menu.

Example:

$menu = (new CliMenuBuilder)
    ->addStaticItem('Header 1')
    ->addGroup(function (CliMenuBuilder $b) {
        $b->addRadioItem('Item 1-A', function() {})
            ->addRadioItem('Item 1-B', function() {})
            ->addRadioItem('Item 1-C', function() {})
        ;
    })
    ->addLineBreak('---')
    ->addStaticItem('Header 2')
    ->addGroup(function (CliMenuBuilder $b) {
        $b->addRadioItem('Item 2-A', function() {})
            ->addRadioItem('Item 2-B', function() {})
            ->addRadioItem('Item 2-C', function() {})
        ;
    })
    ->build();

$menu->open();

This would look identical to the GIF above.

If no items are defined,

$menu = (new CliMenuBuilder)
    ->addStaticItem('Header 1')
    ->addGroup(function (CliMenuBuilder $b) {
        $b->addRadioItem('Item 1-A', function() {})
            ->addRadioItem('Item 1-B', function() {})
            ->addRadioItem('Item 1-C', function() {})
        ;
    })
    ->addLineBreak('---')
    ->addStaticItem('Header 2')
    ->addGroup(function (CliMenuBuilder $b) {
    })
    ->build();

$menu->open();

then it acts as if the group isn't defined at all:

image

This will help group RadioItems in a vertical manner (without needing to use SplitItem), and allow grouping other item types for non-Menu work.

In addition, I would suggest changing RadioItem::getSelectAction() to use this group feature to disable other items within the same group, vs using SplitItem.

If the radio item does not belong to a group, behave as it already does and toggle off other radio items within the same CliMenu object.

edit:

Thinking about this, for initial PR it would be good to keep it simple and not give this class any styling at all. Simply a container, nothing else, but I could see it expending to keeping its own copy of styles and applying them to any children items.

So this would basically end up being a submenu that's visible on the current menu without needing to select an item to view the children items within.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions