yiisoft / yii-bootstrap5

Yii Framework Bootstrap 5 support
https://www.yiiframework.com/
BSD 3-Clause "New" or "Revised" License
62 stars 19 forks source link

New Nav hierarchy (Discussion) #156

Open Gerych1984 opened 1 month ago

Gerych1984 commented 1 month ago

Good day everyone. As we can see - the Nav::class widget can exist on its own or as part of the Tabs/Pills. I propose a new, simplified version for this:

  1. AbstractNav - abstract class for Nav. Can be used for base to (user) custom navigations 1.1. Nav - base navigations as in documentation 1.2. Tabs - navigation with some content 1.3. Pills (?)

This way Tabs no longer needs to duplicate the settings of Nav, and Nav in turn can easily become a variation of tabs wo content

terabytesoftw commented 1 month ago

If it makes sense, in this case i think it would be better to create a new component, Menu::widget, that is responsible for generating all the navigation for all the components.

Gerych1984 commented 1 month ago

If it makes sense, in this case i think it would be better to create a new component, Menu::widget, that is responsible for generating all the navigation for all the components.

I would split into separate, lighter widgets each with their own functionality. It would probably be easier to maintain than a single “bundle”

terabytesoftw commented 1 month ago

If that's what i mean, could you give me an example of what the syntax would be, to make it clearer?

Gerych1984 commented 1 month ago

If that's what i mean, could you give me an example of what the syntax would be, to make it clearer?

Pseudo example with 3 classes

abstract class AbstractNav extends Widget
{
     public function items(array $items): static
     {
          //some code
     }

      public function options(array $options): static
      {
           //some code
      }

      public function itemOptions(array $options): static
      {
          //some code
      }

      public function type(?string $type): static
     { 
           //set nav type here 
      }

     //etc only for base navigation
}
final class Nav extends AbstractNav 
{
      //maybe empty class just for resolve abstraction
}
final class Tabs extends AbstractNav
{
     public function tabContentOptions(array $options): self
     {
          //some code here
     }

     public function tabPaneOptions(array $options): self
     {
          //some code here
      }
}

And now we have

// simple nav
$nav = Nav::widget()
                  ->options([***])
                 ->items([****]);

// simple nav styled as `Pills`
$styledNav = $nav->type('nav-pills');

// nav with tabs
$tabs = Tabs::widget()
              ->options([***])
               ->items([****])
               ->tabContentOptions([***]);
terabytesoftw commented 1 month ago

What if we create a class to generate the navigation items, and we could pass a varadic, or an array that in turn creates the item generation widget, we would have the Yii2 form, and the new form with ide suggestion, and thus validate the contents of the array?

Gerych1984 commented 1 month ago

What if we create a class to generate the navigation items, and we could pass a varadic, or an array that in turn creates the item generation widget, we would have the Yii2 form, and the new form with ide suggestion, and thus validate the contents of the array?

Can you give me an example?

terabytesoftw commented 1 month ago

It could be something like this.

NavBar::widget()
    ->menu(
        Menu::widget()
             ->currentPath('/home')
             ->id('menu_1')
             ->items(
                Item::widget()->label('Home')->link('/home'),
                Item::widget()->label('Link')->link('/link'),
                Item::widget()->label('Disable')->link('/disable')->disable(),
             )
    )
    ->render();
Gerych1984 commented 1 month ago

It could be something like this.

NavBar::widget()
    ->menu(
        Menu::widget()
             ->currentPath('/home')
             ->id('menu_1')
             ->items(
                Item::widget()->label('Home')->link('/home'),
                Item::widget()->label('Link')->link('/link'),
                Item::widget()->label('Disable')->link('/disable')->disable(),
             )
    )
    ->render();

Yes - Item::widget is better than simple array

Gerych1984 commented 1 month ago

I can do it if no one has any objections or notes.

terabytesoftw commented 1 month ago

That's fine by me.

terabytesoftw commented 1 month ago

I'll help with the review, we're going to refactor all the widgets, but let's work on them one at a time, okay?

Gerych1984 commented 1 month ago

I'll help with the review, we're going to refactor all the widgets, but let's work on them one at a time, okay?

I'll try to do a draft within a couple days

Gerych1984 commented 1 month ago

I'll help with the review, we're going to refactor all the widgets, but let's work on them one at a time, okay?

https://github.com/yiisoft/yii-bootstrap5/pull/157 this PR as example