Skip to content

Checkbox + Radio item-level styling #204

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

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
* [Remove Exit Button](#remove-exit-button)
* [Items](#appearance)
* [Selectable Item](#selectable-item)
* [Checkable Item](#checkable-item)
* [Checkbox Item](#checkbox-item)
* [Radio Item](#radio-item)
* [Line Break Item](#line-break-item)
* [Static Item](#static-item)
Expand Down Expand Up @@ -501,7 +501,7 @@ $menu = (new CliMenuBuilder)
There a few different types of items you can add to your menu

* Selectable Item - This is the type of item you need for something to be selectable (you can hit enter and it will invoke your callable)
* Checkable Item - This is a checkbox type of item that keeps track of its toggled state to show a different marker.
* Checkbox Item - This is a checkbox type of item that keeps track of its toggled state to show a different marker.
* Radio Item - This is a radio type of item that keeps track of its toggled state to show a different marker. Disables all other radios within its `CliMenu` level.
* Line Break Item - This is used to break up areas, it can span multiple lines and will be the width of Menu. Whatever string is passed will be repeated.
* Static Item - This will print whatever text is passed, useful for headings.
Expand Down Expand Up @@ -548,7 +548,7 @@ $menu = (new CliMenuBuilder)
Note: You can add as many items as you want and they can all have a different action. The action is the second parameter
and must be a valid PHP `callable`. Try using an `Invokable` class to keep your actions easily testable.

### Checkable Item
### Checkbox Item

```php
<?php
Expand All @@ -561,9 +561,9 @@ $callable = function (CliMenu $menu) {
};

$menu = (new CliMenuBuilder)
->addCheckableItem('Item 1', $callable)
->addCheckableItem('Item 2', $callable)
->addCheckableItem('Item 3', $callable)
->addCheckboxItem('Item 1', $callable)
->addCheckboxItem('Item 2', $callable)
->addCheckboxItem('Item 3', $callable)
->build();
```

Expand Down Expand Up @@ -719,7 +719,7 @@ Split Items allows you to add multiple items on the same row. The full width of

You can set the number of spaces separating items using `->setGutter()` (defaults to 2).

Only Selectable, Checkable, Radio, Static and SubMenu items are currently allowed inside a Split Item.
Only Selectable, Checkbox, Radio, Static and SubMenu items are currently allowed inside a Split Item.

```php
<?php
Expand Down Expand Up @@ -752,7 +752,7 @@ $menu->open();
There are a few things to note about the syntax and builder process here:

1. The first parameter to `addSplitItem` is a closure, which will be invoked with a new instance of `SplitItemBuilder` which you can use to add items to the split item.
2. You can call `addItem`, `addCheckableItem`, `addRadioItem`, `addSubMenu` and `addStaticItem` on the `SplitItemBuilder`.
2. You can call `addItem`, `addCheckboxItem`, `addRadioItem`, `addSubMenu` and `addStaticItem` on the `SplitItemBuilder`.
3. `SplitItemBuilder` has a fluent interface so you can chain method calls.

### Disabling Items & Sub Menus
Expand Down Expand Up @@ -811,16 +811,19 @@ $menu = (new CliMenuBuilder)
->build();
```

You may also change the marker for `\PhpSchool\CliMenu\MenuItem\CheckableItem`:
You may also change the marker for `\PhpSchool\CliMenu\MenuItem\CheckboxItem`:

```php
<?php

use PhpSchool\CliMenu\Builder\CliMenuBuilder;
use PhpSchool\CliMenu\Style\CheckboxStyle;

$menu = (new CliMenuBuilder)
->setUncheckedMarker('[○] ')
->setCheckedMarker('[●] ')
->checkboxStyle(function (CheckboxStyle $style) {
$style->setMarkerOff('[○] ')
->setMarkerOn('[●] ');
})
->build();
```

Expand All @@ -830,10 +833,13 @@ and for `\PhpSchool\CliMenu\MenuItem\RadioItem`:
<?php

use PhpSchool\CliMenu\Builder\CliMenuBuilder;
use PhpSchool\CliMenu\Style\RadioStyle;

$menu = (new CliMenuBuilder)
->setUnradioMarker('[ ] ')
->setRadioMarker('[✔] ')
->radioStyle(function (RadioStyle $style) {
$style->setMarkerOff('[ ] ')
->setMarkerOn('[✔] ');
})
->build();
```

Expand Down
35 changes: 0 additions & 35 deletions examples/checkable-item.php

This file was deleted.

38 changes: 38 additions & 0 deletions examples/checkbox-item.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

use PhpSchool\CliMenu\CliMenu;
use PhpSchool\CliMenu\Builder\CliMenuBuilder;
use PhpSchool\CliMenu\Style\CheckboxStyle;

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

$itemCallable = function (CliMenu $menu) {
echo $menu->getSelectedItem()->getText();
};

$menu = (new CliMenuBuilder)
->setTitle('Select a Language')
->addSubMenu('Compiled', function (CliMenuBuilder $b) use ($itemCallable) {
$b->setTitle('Compiled Languages')
->addCheckboxItem('Rust', $itemCallable)
->addCheckboxItem('C++', $itemCallable)
->addCheckboxItem('Go', $itemCallable)
->addCheckboxItem('Java', $itemCallable)
->addCheckboxItem('C', $itemCallable)
;
})
->addSubMenu('Interpreted', function (CliMenuBuilder $b) use ($itemCallable) {
$b->setTitle('Interpreted Languages')
->checkboxStyle(function (CheckboxStyle $style) {
$style->setMarkerOff('[○] ')
->setMarkerOn('[●] ');
})
->addCheckboxItem('PHP', $itemCallable)
->addCheckboxItem('Javascript', $itemCallable)
->addCheckboxItem('Ruby', $itemCallable)
->addCheckboxItem('Python', $itemCallable)
;
})
->build();

$menu->open();
7 changes: 5 additions & 2 deletions examples/radio-item.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use PhpSchool\CliMenu\CliMenu;
use PhpSchool\CliMenu\Builder\CliMenuBuilder;
use PhpSchool\CliMenu\Style\RadioStyle;

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

Expand All @@ -22,8 +23,10 @@
})
->addSubMenu('Interpreted', function (CliMenuBuilder $b) use ($itemCallable) {
$b->setTitle('Interpreted Languages')
->setUnradioMarker('[ ] ')
->setRadioMarker('[✔] ')
->radioStyle(function (RadioStyle $style) {
$style->setMarkerOff('[ ] ')
->setMarkerOn('[✔] ');
})
->addRadioItem('PHP', $itemCallable)
->addRadioItem('Javascript', $itemCallable)
->addRadioItem('Ruby', $itemCallable)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
->setTitle('Select a Language')
->addSplitItem(function (SplitItemBuilder $b) use ($itemCallable) {
$b->setGutter(5)
->addCheckableItem('Rust', $itemCallable)
->addCheckableItem('C++', $itemCallable)
->addCheckableItem('Go', $itemCallable)
->addCheckableItem('Java', $itemCallable)
->addCheckableItem('C', $itemCallable)
->addCheckboxItem('Rust', $itemCallable)
->addCheckboxItem('C++', $itemCallable)
->addCheckboxItem('Go', $itemCallable)
->addCheckboxItem('Java', $itemCallable)
->addCheckboxItem('C', $itemCallable)
;
})
->build();
Expand Down
106 changes: 74 additions & 32 deletions src/Builder/CliMenuBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use PhpSchool\CliMenu\Action\GoBackAction;
use PhpSchool\CliMenu\Exception\InvalidShortcutException;
use PhpSchool\CliMenu\MenuItem\AsciiArtItem;
use PhpSchool\CliMenu\MenuItem\CheckableItem;
use PhpSchool\CliMenu\MenuItem\CheckboxItem;
use PhpSchool\CliMenu\MenuItem\LineBreakItem;
use PhpSchool\CliMenu\MenuItem\MenuItemInterface;
use PhpSchool\CliMenu\MenuItem\MenuMenuItem;
Expand All @@ -16,6 +16,8 @@
use PhpSchool\CliMenu\MenuItem\SplitItem;
use PhpSchool\CliMenu\MenuItem\StaticItem;
use PhpSchool\CliMenu\MenuStyle;
use PhpSchool\CliMenu\Style\CheckboxStyle;
use PhpSchool\CliMenu\Style\RadioStyle;
use PhpSchool\CliMenu\Terminal\TerminalFactory;
use PhpSchool\Terminal\Terminal;

Expand Down Expand Up @@ -132,13 +134,16 @@ public function addItems(array $items) : self
return $this;
}

public function addCheckableItem(
public function addCheckboxItem(
string $text,
callable $itemCallable,
bool $showItemExtra = false,
bool $disabled = false
) : self {
$this->addMenuItem(new CheckableItem($text, $itemCallable, $showItemExtra, $disabled));
$item = (new CheckboxItem($text, $itemCallable, $showItemExtra, $disabled))
->setStyle($this->menu->getCheckboxStyle());

$this->addMenuItem($item);

return $this;
}
Expand All @@ -149,7 +154,10 @@ public function addRadioItem(
bool $showItemExtra = false,
bool $disabled = false
) : self {
$this->addMenuItem(new RadioItem($text, $itemCallable, $showItemExtra, $disabled));
$item = (new RadioItem($text, $itemCallable, $showItemExtra, $disabled))
->setStyle($this->menu->getRadioStyle());

$this->addMenuItem($item);

return $this;
}
Expand Down Expand Up @@ -194,6 +202,18 @@ public function addSubMenu(string $text, \Closure $callback) : self
$menu->setStyle($this->menu->getStyle());
}

if (!$menu->getCheckboxStyle()->getIsCustom()) {
$menu->checkboxStyle(function (CheckboxStyle $style) {
$style->fromArray($this->menu->getCheckboxStyle()->toArray());
});
}

if (!$menu->getRadioStyle()->getIsCustom()) {
$menu->radioStyle(function (RadioStyle $style) {
$style->fromArray($this->menu->getRadioStyle()->toArray());
});
}

$this->menu->addItem($item = new MenuMenuItem(
$text,
$menu,
Expand All @@ -216,6 +236,14 @@ public function addSubMenuFromBuilder(string $text, CliMenuBuilder $builder) : s
$menu->setStyle($this->menu->getStyle());
}

$menu->checkboxStyle(function (CheckboxStyle $style) {
$style->fromArray($this->menu->getCheckboxStyle()->toArray());
});

$menu->radioStyle(function (RadioStyle $style) {
$style->fromArray($this->menu->getRadioStyle()->toArray());
});

$this->menu->addItem($item = new MenuMenuItem(
$text,
$menu,
Expand Down Expand Up @@ -302,6 +330,14 @@ public function addSplitItem(\Closure $callback) : self
}

$callback($builder);

$builder->checkboxStyle(function (CheckboxStyle $style) {
$style->fromArray($this->menu->getCheckboxStyle()->toArray());
});

$builder->radioStyle(function (RadioStyle $style) {
$style->fromArray($this->menu->getRadioStyle()->toArray());
});

$this->menu->addItem($splitItem = $builder->build());

Expand Down Expand Up @@ -417,34 +453,6 @@ public function setSelectedMarker(string $marker) : self
return $this;
}

public function setUncheckedMarker(string $marker) : self
{
$this->style->setUncheckedMarker($marker);

return $this;
}

public function setCheckedMarker(string $marker) : self
{
$this->style->setCheckedMarker($marker);

return $this;
}

public function setUnradioMarker(string $marker) : self
{
$this->style->setUnradioMarker($marker);

return $this;
}

public function setRadioMarker(string $marker) : self
{
$this->style->setRadioMarker($marker);

return $this;
}

public function setItemExtra(string $extra) : self
{
$this->style->setItemExtra($extra);
Expand Down Expand Up @@ -558,4 +566,38 @@ public function build() : CliMenu

return $this->menu;
}

/**
* Use as
*
->checkboxStyle(function (CheckboxStyle $style) {
$style->setMarkerOff('- ');
})
*
* @param callable $itemCallable
* @return $this
*/
public function checkboxStyle(callable $itemCallable) : self
{
$this->menu->checkboxStyle($itemCallable);

return $this;
}

/**
* Use as
*
->radioStyle(function (RadioStyle $style) {
$style->setMarkerOff('- ');
})
*
* @param callable $itemCallable
* @return $this
*/
public function radioStyle(callable $itemCallable) : self
{
$this->menu->radioStyle($itemCallable);

return $this;
}
}
Loading