diff --git a/README.md b/README.md index 0cea2d90..59f814eb 100644 --- a/README.md +++ b/README.md @@ -791,6 +791,32 @@ $menu = (new CliMenuBuilder) ->build(); ``` +If no items have display extra set to true, then the item extra will not be displayed. If you toggle the item to show +it's item extra in a callback or at runtime it will render incorrectly. + +In order to fix that you need to tell the menu to display item extra explicitly. You can do this when constructing the +menu like so: + +```php +setItemExtra('✔') + ->addItem('Exercise 1', function (CliMenu $menu) { + $selectedItem = $menu->getSelectedItem(); + if ($selectedItem->showsItemExtra()) { + $selectedItem->hideItemExtra(); + } else { + $selectedItem->showItemExtra(); + } + }) + ->displayExtra() + ->build(); +``` + ## Menu Methods The next set of documentation applies to methods available directly on the `\PhpSchool\CliMenu\CliMenu` instance. Typically diff --git a/examples/item-extra-toggling.php b/examples/item-extra-toggling.php new file mode 100644 index 00000000..87a503ed --- /dev/null +++ b/examples/item-extra-toggling.php @@ -0,0 +1,28 @@ +getSelectedItem()->showsItemExtra()) { + $menu->getSelectedItem()->hideItemExtra(); + } else { + $menu->getSelectedItem()->showItemExtra(); + } + $menu->redraw(); + echo $menu->getSelectedItem()->getText(); +}; + +$menu = (new CliMenuBuilder) + ->setTitle('Basic CLI Menu Custom Item Extra') + ->addItem('First Item', $itemCallable) + ->addItem('Second Item', $itemCallable) + ->addItem('Third Item', $itemCallable) + ->setItemExtra('[COMPLETE!]') + ->displayExtra() + ->addLineBreak('-') + ->build(); + +$menu->open(); diff --git a/src/Builder/CliMenuBuilder.php b/src/Builder/CliMenuBuilder.php index 7bd4188d..a821ae42 100644 --- a/src/Builder/CliMenuBuilder.php +++ b/src/Builder/CliMenuBuilder.php @@ -425,6 +425,9 @@ public function setItemExtra(string $extra) : self { $this->style->setItemExtra($extra); + //if we customise item extra, it means we most likely want to display it + $this->displayExtra(); + return $this; } @@ -505,6 +508,13 @@ public function disableDefaultItems() : self return $this; } + public function displayExtra() : self + { + $this->style->setDisplaysExtra(true); + + return $this; + } + private function itemsHaveExtra(array $items) : bool { return !empty(array_filter($items, function (MenuItemInterface $item) { @@ -518,7 +528,9 @@ public function build() : CliMenu $this->menu->addItems($this->getDefaultItems()); } - $this->style->setDisplaysExtra($this->itemsHaveExtra($this->menu->getItems())); + if (!$this->style->getDisplaysExtra()) { + $this->style->setDisplaysExtra($this->itemsHaveExtra($this->menu->getItems())); + } return $this->menu; } diff --git a/test/Builder/CliMenuBuilderTest.php b/test/Builder/CliMenuBuilderTest.php index 70e72c68..fd1fc879 100644 --- a/test/Builder/CliMenuBuilderTest.php +++ b/test/Builder/CliMenuBuilderTest.php @@ -820,6 +820,35 @@ public function testAddSplitItemWithClosureBinding() : void $this->checkItems($menu->getItems()[0]->getItems(), $expected); } + public function testDisplayExtraForcesExtraToBeDisplayedWhenNoItemsDisplayExtra() : void + { + $cb = function () { + }; + $builder = new CliMenuBuilder; + $builder->addItem('Item 1', $cb); + $builder->addItem('Item 2', $cb); + $builder->displayExtra(); + + $menu = $builder->build(); + + self::assertTrue($menu->getStyle()->getDisplaysExtra()); + } + + public function testModifyingItemExtraForcesExtraToBeDisplayedWhenNoItemsDisplayExtra() : void + { + $cb = function () { + }; + $builder = new CliMenuBuilder; + $builder->addItem('Item 1', $cb); + $builder->addItem('Item 2', $cb); + $builder->setItemExtra('DONE'); + + $menu = $builder->build(); + + self::assertTrue($menu->getStyle()->getDisplaysExtra()); + } + + private function checkMenuItems(CliMenu $menu, array $expected) : void { $this->checkItems($menu->getItems(), $expected);