1010use macgyer \yii2materializecss \assets \MaterializePluginAsset ;
1111use macgyer \yii2materializecss \lib \BaseWidget ;
1212use macgyer \yii2materializecss \lib \Html ;
13+ use macgyer \yii2materializecss \widgets \Button ;
14+ use macgyer \yii2materializecss \widgets \Icon ;
1315use Yii ;
16+ use yii \helpers \ArrayHelper ;
1417
1518/**
1619 * NavBar renders a navbar HTML component.
@@ -99,13 +102,56 @@ class NavBar extends BaseWidget
99102 */
100103 public $ wrapperOptions = [];
101104
105+ /**
106+ * @var array the side nav configuration options.
107+ * See SideNav|SideNav for details.
108+ */
109+ public $ sidenavOptions = [];
110+
111+ /**
112+ * @var bool whether the side nav shall be rendered.
113+ */
114+ public $ renderSidenav = true ;
115+
116+ /**
117+ * @var array the options for the underlying JS sideNav() plugin.
118+ * @see https://materializecss.com/sidenav.html#options
119+ */
120+ public $ sidenavClientOptions = [];
121+
122+ /**
123+ * @var array the configuration options for the toggle button.
124+ * The toggle button is rendered by the [[\macgyer\yii2materializecss\widgets\Button|Button]] widget. See the docs for all available options.
125+ *
126+ * @see \macgyer\yii2materializecss\widgets\Button|Button
127+ */
128+ public $ sidenavToggleButtonOptions = [];
129+
130+ /**
131+ * @var array list of items in the nav widget. Each array element represents a single
132+ * menu item which can be either a string or an array with the following structure:
133+ *
134+ * - label: string, required, the nav item label.
135+ * - url: optional, the item's URL. Defaults to "#".
136+ * - visible: boolean, optional, whether this menu item is visible. Defaults to true.
137+ * - linkOptions: array, optional, the HTML attributes of the item's link.
138+ * - options: array, optional, the HTML attributes of the item container (LI).
139+ * - active: boolean, optional, whether the item should be on active state or not.
140+ * - dropDownOptions: array, optional, the HTML options that will passed to the [[Dropdown]] widget.
141+ * - items: array|string, optional, the configuration array for creating a [[Dropdown]] widget,
142+ * or a string representing the dropdown menu. Note that Bootstrap does not support sub-dropdown menus.
143+ * - encode: boolean, optional, whether the label will be HTML-encoded. If set, supersedes the $encodeLabels option for only this item.
144+ *
145+ * If a menu item is a string, it will be rendered directly without HTML encoding.
146+ */
147+ public $ sidenavItems = [];
148+
102149 /**
103150 * Initializes the widget.
104151 */
105152 public function init ()
106153 {
107154 parent ::init ();
108- $ this ->clientOptions = false ;
109155 $ html = [];
110156
111157 if (empty ($ this ->options ['role ' ])) {
@@ -140,9 +186,18 @@ public function init()
140186 */
141187 public function run ()
142188 {
189+ if ($ this ->renderSidenav ) {
190+ $ sidenavId = $ this ->getUniqueId ('sidenav_ ' );
191+ $ this ->initSidenav ($ sidenavId );
192+ }
193+
143194 $ html = [];
144195 $ html [] = Html::endTag ('div ' ); // container
145196
197+ if ($ this ->renderSidenav ) {
198+ $ html [] = $ this ->renderSidenavToggleButton ();
199+ }
200+
146201 $ html [] = Html::endTag ('div ' ); // nav-wrapper
147202
148203 $ html [] = Html::endTag ('nav ' );
@@ -151,8 +206,48 @@ public function run()
151206 $ html [] = Html::endTag ('div ' );
152207 }
153208
154- MaterializePluginAsset::register ($ this ->getView ());
209+ if ($ this ->renderSidenav ) {
210+ $ html [] = $ this ->renderSidenav ($ sidenavId );
211+ }
155212
156213 return implode ("\n" , $ html );
157214 }
215+
216+ protected function initSidenav ($ sidenavId )
217+ {
218+ $ this ->sidenavToggleButtonOptions = ArrayHelper::merge ([
219+ 'label ' => false ,
220+ 'icon ' => [
221+ 'name ' => 'menu '
222+ ],
223+ 'type ' => Button::TYPE_FLAT ,
224+ ], $ this ->sidenavToggleButtonOptions );
225+
226+ if (!isset ($ this ->sidenavToggleButtonOptions ['options ' ]['data-target ' ])) {
227+ $ this ->sidenavToggleButtonOptions ['options ' ]['data-target ' ] = $ sidenavId ;
228+ }
229+
230+ Html::addCssClass ($ this ->sidenavToggleButtonOptions ['options ' ], ['trigger ' => 'sidenav-trigger ' ]);
231+ }
232+
233+ /**
234+ * Renders the side navigation and corresponding toggle button.
235+ * @param $sidenavId
236+ * @return string the rendered side navigation markup.
237+ * @throws \Exception
238+ */
239+ protected function renderSidenav ($ sidenavId )
240+ {
241+ return SideNav::widget ([
242+ 'items ' => $ this ->sidenavItems ,
243+ 'renderToggleButton ' => false ,
244+ 'clientOptions ' => $ this ->sidenavClientOptions ,
245+ 'options ' => ['id ' => $ sidenavId ],
246+ ]);
247+ }
248+
249+ protected function renderSidenavToggleButton ()
250+ {
251+ return Button::widget ($ this ->sidenavToggleButtonOptions );
252+ }
158253}
0 commit comments