├── Badge.php ├── Button.php ├── ButtonFixedAction.php ├── Card.php ├── Collection.php ├── Dropdown.php ├── Icon.php ├── LICENSE ├── MaterializeCssAsset.php ├── MaterializeJsAsset.php ├── MaterializePluginAsset.php ├── Nav.php ├── NavBar.php ├── Preloader.php ├── Progress.php ├── README.md ├── Widget.php └── composer.json /Badge.php: -------------------------------------------------------------------------------- 1 | 'Action', 13 | * 'options' => ['class' => 'new'], 14 | * ]); 15 | * ``` 16 | * @see http://materializecss.com/badges.html 17 | * @author webmaxx 18 | * @since 2.0 19 | */ 20 | class Badge extends Widget 21 | { 22 | /** 23 | * @var string the tag to use to render the badge 24 | */ 25 | public $tagName = 'span'; 26 | /** 27 | * @var string the button label 28 | */ 29 | public $label = ''; 30 | /** 31 | * @var boolean whether the label should be HTML-encoded. 32 | */ 33 | public $encodeLabel = true; 34 | /** 35 | * @var string default css class for badge 36 | */ 37 | public $defaultClass = 'badge'; 38 | 39 | /** 40 | * Initializes the widget. 41 | * If you override this method, make sure you call the parent implementation first. 42 | */ 43 | public function init() 44 | { 45 | parent::init(); 46 | $this->clientOptions = false; 47 | if ($this->defaultClass) 48 | Html::addCssClass($this->options, $this->defaultClass); 49 | } 50 | 51 | /** 52 | * Renders the widget. 53 | */ 54 | public function run() 55 | { 56 | return Html::tag($this->tagName, $this->encodeLabel ? Html::encode($this->label) : $this->label, $this->options); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Button.php: -------------------------------------------------------------------------------- 1 | 'Action', 13 | * 'options' => ['class' => 'btn-large'], 14 | * ]); 15 | * ``` 16 | * @see http://materializecss.com/buttons.html 17 | * @author webmaxx 18 | * @since 2.0 19 | */ 20 | class Button extends Widget 21 | { 22 | /** 23 | * @var string the tag to use to render the button 24 | */ 25 | public $tagName = 'button'; 26 | /** 27 | * @var string the button label 28 | */ 29 | public $label = 'Button'; 30 | /** 31 | * @var boolean whether the label should be HTML-encoded. 32 | */ 33 | public $encodeLabel = true; 34 | /** 35 | * @var string default css class for button 36 | */ 37 | public $defaultClass = 'btn'; 38 | 39 | /** 40 | * Initializes the widget. 41 | * If you override this method, make sure you call the parent implementation first. 42 | */ 43 | public function init() 44 | { 45 | parent::init(); 46 | $this->clientOptions = false; 47 | if ($this->defaultClass) 48 | Html::addCssClass($this->options, $this->defaultClass); 49 | } 50 | 51 | /** 52 | * Renders the widget. 53 | */ 54 | public function run() 55 | { 56 | $this->registerPlugin('button'); 57 | return Html::tag($this->tagName, $this->encodeLabel ? Html::encode($this->label) : $this->label, $this->options); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ButtonFixedAction.php: -------------------------------------------------------------------------------- 1 | 'Action', 14 | * 'options' => ['class' => 'btn-large'], 15 | * 'wrapOptions' => ['style' => 'bottom: 45px; right: 24px;'], 16 | * 'buttons' => [ 17 | * Button::widget(['label' => 'A']), 18 | * ['label' => 'B'], 19 | * ], 20 | * ]); 21 | * ``` 22 | * @see http://materializecss.com/buttons.html 23 | * @author webmaxx 24 | * @since 2.0 25 | */ 26 | class ButtonFixedAction extends Widget 27 | { 28 | /** 29 | * @var string the tag to use to render the button 30 | */ 31 | public $tagName = 'button'; 32 | /** 33 | * @var string the button label 34 | */ 35 | public $label = 'Button'; 36 | /** 37 | * @var boolean whether the label should be HTML-encoded. 38 | */ 39 | public $encodeLabel = true; 40 | /** 41 | * @var string default css class for button 42 | */ 43 | public $defaultClass = 'btn'; 44 | /** 45 | * @var array the HTML attributes for the widget container tag. 46 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. 47 | */ 48 | public $wrapOptions = []; 49 | /** 50 | * @var string default css class for button wrapper 51 | */ 52 | public $defaultWrapClass = 'fixed-action-btn'; 53 | /** 54 | * @var array list of buttons. Each array element represents a single button 55 | * which can be specified as a string or an array of the following structure: 56 | * 57 | * - label: string, required, the button label. 58 | * - options: array, optional, the HTML attributes of the button. 59 | */ 60 | public $buttons = []; 61 | /** 62 | * @var boolean whether to HTML-encode the button labels. 63 | */ 64 | public $encodeLabels = true; 65 | 66 | /** 67 | * Initializes the widget. 68 | * If you override this method, make sure you call the parent implementation first. 69 | */ 70 | public function init() 71 | { 72 | parent::init(); 73 | $this->clientOptions = false; 74 | if ($this->defaultWrapClass) 75 | Html::addCssClass($this->wrapOptions, $this->defaultWrapClass); 76 | if ($this->defaultClass) 77 | Html::addCssClass($this->options, $this->defaultClass); 78 | } 79 | 80 | /** 81 | * Renders the widget. 82 | */ 83 | public function run() 84 | { 85 | MaterializeAsset::register($this->getView()); 86 | return Html::tag( 87 | 'div', 88 | Html::tag($this->tagName, $this->encodeLabel ? Html::encode($this->label) : $this->label, $this->options) . Html::tag('ul', $this->renderButtons()), 89 | $this->wrapOptions 90 | ); 91 | } 92 | 93 | /** 94 | * Generates the buttons that compound the group as specified on [[buttons]]. 95 | * @return string the rendering result. 96 | */ 97 | protected function renderButtons() 98 | { 99 | $buttons = []; 100 | foreach ($this->buttons as $button) { 101 | if (is_array($button)) { 102 | $button['view'] = $this->getView(); 103 | $button['defaultClass'] = false; 104 | if (!isset($button['encodeLabel'])) { 105 | $button['encodeLabel'] = $this->encodeLabels; 106 | } 107 | $buttons[] = Html::tag('li', Button::widget($button)); 108 | } else { 109 | $buttons[] = Html::tag('li', $button); 110 | } 111 | } 112 | 113 | return implode("\n", $buttons); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Card.php: -------------------------------------------------------------------------------- 1 | 'Title', 21 | * 'content' => 'Content', 22 | * ]); 23 | * ``` 24 | * @see http://materializecss.com/cards.html 25 | * @author p0larbeer 26 | * @since 2.0 27 | */ 28 | class Card extends Widget 29 | { 30 | /** 31 | * @var string src for render image block 32 | */ 33 | public $image; 34 | /** 35 | * @var string the title of card 36 | */ 37 | public $title; 38 | /** 39 | * @var boolean whether to show title section. * 40 | */ 41 | public $renderTitle = true; 42 | /** 43 | * @var string html code to render on content block of card 44 | */ 45 | public $content; 46 | /** 47 | * @var string html code to render on action block of card; 48 | */ 49 | public $action; 50 | /** 51 | * @var boolean whether the content should be HTML-encoded. 52 | */ 53 | public $encodeContent = true; 54 | /** 55 | * @var boolean whether the action should be HTML-encoded. 56 | */ 57 | public $encodeAction = true; 58 | /** 59 | * @var boolean whether the title should be HTML-encoded. 60 | */ 61 | public $encodeTitle = true; 62 | /** 63 | * @var string default css class for card 64 | */ 65 | public $defaultClass = 'card'; 66 | 67 | /** 68 | * Initializes the widget. 69 | * If you override this method, make sure you call the parent implementation first. 70 | */ 71 | public function init() 72 | { 73 | parent::init(); 74 | $this->clientOptions = false; 75 | if ($this->defaultClass) 76 | Html::addCssClass($this->options, $this->defaultClass); 77 | } 78 | 79 | /** 80 | * Renders the widget. 81 | */ 82 | public function run() 83 | { 84 | //return Html::tag($this->tagName, $this->encodeLabel ? Html::encode($this->label) : $this->label, $this->options); 85 | $html = ''; 86 | if ($this->image !== null) { 87 | $html .= $this->renderImage(); 88 | } 89 | if ($this->content !== null) { 90 | $html .= $this->renderContent(); 91 | } 92 | if ($this->action !== null) { 93 | $html .= $this->renderAction(); 94 | } 95 | if ($this->defaultClass) { 96 | Html::addCssClass($this->options, $this->defaultClass); 97 | } 98 | return Html::tag('div', $html, $this->options); 99 | } 100 | 101 | /** 102 | * Renders the title. 103 | * @return string the rendering result. 104 | */ 105 | public function renderTitle() 106 | { 107 | return Html::tag( 108 | 'span', 109 | $this->encodeTitle ? Html::encode($this->title) : $this->title, 110 | ['class' => 'card-title'] 111 | ); 112 | } 113 | 114 | /** 115 | * Renders the action. 116 | * @return string the rendering result. 117 | */ 118 | public function renderAction() 119 | { 120 | return Html::tag( 121 | 'div', 122 | $this->encodeAction ? Html::encode($this->action) : $this->action, 123 | ['class' => 'card-action'] 124 | ); 125 | } 126 | 127 | /** 128 | * Renders the image. 129 | * @return string the rendering result. 130 | */ 131 | public function renderImage() 132 | { 133 | $html = Html::img($this->image); 134 | if ($this->renderTitle) { 135 | $html .= $this->renderTitle(); 136 | } 137 | return Html::tag( 138 | 'div', 139 | $html, 140 | ['class' => 'card-image'] 141 | ); 142 | } 143 | 144 | /** 145 | * Renders the content. 146 | * @return string the rendering result. 147 | */ 148 | public function renderContent() 149 | { 150 | if ($this->renderTitle) { 151 | $this->encodeContent = false; 152 | } 153 | if ($this->image === null) { 154 | $title = $this->renderTitle(); 155 | } else { 156 | $title = ''; 157 | } 158 | return Html::tag( 159 | 'div', 160 | $this->encodeContent ? Html::encode($title . $this->content) : $title . $this->content, 161 | ['class' => 'card-content'] 162 | ); 163 | } 164 | 165 | } 166 | 167 | -------------------------------------------------------------------------------- /Collection.php: -------------------------------------------------------------------------------- 1 | [ 13 | * 'class' => 'with-header', 14 | * ], 15 | * 'items' => [ 16 | * ['label' => Html::tag('h4', 'header'), 'type' => 'header'], 17 | * ['label' => 'test'], 18 | * ['label' => 'test2'], 19 | * ], 20 | * ]); 21 | * ``` 22 | * or 23 | * 24 | * ```php 25 | * echo Collection::widget([ 26 | * 'tagName' => 'div', 27 | * 'itemTagName' => 'a', 28 | * 'items' => [ 29 | * ['label' => 'test', 'options' => ['href' => '/']], 30 | * ['label' => 'test2', 'options' => ['href' => '/', 'class' => 'active']], 31 | * ['label' => 'test3', 'options' => ['href' => '/']], 32 | * ], 33 | * ]); 34 | * ``` 35 | * @see http://materializecss.com/collections.html 36 | * @author webmaxx 37 | * @since 2.0 38 | */ 39 | class Collection extends Widget 40 | { 41 | /** 42 | * @var string the tag to use to render the collection 43 | */ 44 | public $tagName = 'ul'; 45 | /** 46 | * @var array list of items. Each array element represents a single item 47 | * which can be specified as a string or an array of the following structure: 48 | * 49 | * - label: string, required, the button label. 50 | * - options: array, optional, the HTML attributes of the button. 51 | */ 52 | public $items = []; 53 | /** 54 | * @var string the tag to use to render the collection item 55 | */ 56 | public $itemTagName = 'li'; 57 | /** 58 | * @var boolean whether to HTML-encode the item labels. 59 | */ 60 | public $encodeLabels = true; 61 | /** 62 | * @var string default css class for collection 63 | */ 64 | public $defaultClass = 'collection'; 65 | 66 | /** 67 | * Initializes the widget. 68 | * If you override this method, make sure you call the parent implementation first. 69 | */ 70 | public function init() 71 | { 72 | parent::init(); 73 | $this->clientOptions = false; 74 | if ($this->defaultClass) 75 | Html::addCssClass($this->options, $this->defaultClass); 76 | } 77 | 78 | /** 79 | * Renders the widget. 80 | */ 81 | public function run() 82 | { 83 | MaterializeAsset::register($this->getView()); 84 | return Html::tag($this->tagName, $this->renderItems(), $this->options); 85 | } 86 | 87 | /** 88 | * Generates the buttons that compound the group as specified on [[buttons]]. 89 | * @return string the rendering result. 90 | */ 91 | protected function renderItems() 92 | { 93 | $buttons = []; 94 | foreach ($this->items as $item) { 95 | if (is_array($item)) { 96 | $item['view'] = $this->getView(); 97 | if (!isset($item['tagName'])) { 98 | $item['tagName'] = $this->itemTagName; 99 | } 100 | if (!isset($item['encodeLabel'])) { 101 | $item['encodeLabel'] = $this->encodeLabels; 102 | } 103 | if (!isset($item['type'])) { 104 | Html::addCssClass($item['options'], 'collection-item'); 105 | } else { 106 | Html::addCssClass($item['options'], 'collection-' . $item['type']); 107 | } 108 | if (!isset($item['options'])) { 109 | $item['options'] = []; 110 | } 111 | 112 | $items[] = Html::tag($item['tagName'], $item['label'], $item['options']); 113 | } else { 114 | $items[] = $item; 115 | } 116 | } 117 | 118 | return implode("\n", $items); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Dropdown.php: -------------------------------------------------------------------------------- 1 | [ 16 | * ['label' => 'DropdownA', 'url' => '/'], 17 | * ['label' => 'DropdownB', 'url' => '#'], 18 | * ], 19 | * ]); 20 | * ``` 21 | * @see http://materializecss.com/dropdown.html 22 | * @author webmaxx 23 | * @since 2.0 24 | */ 25 | class Dropdown extends Widget 26 | { 27 | /** 28 | * @var string the tag to use to render the button 29 | */ 30 | public $buttontagName = 'a'; 31 | /** 32 | * @var string the button label 33 | */ 34 | public $buttonLabel = 'Dropdown'; 35 | /** 36 | * @var boolean whether the label should be HTML-encoded. 37 | */ 38 | public $buttonEncodeLabel = true; 39 | /** 40 | * @var array the HTML attributes of the button. 41 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. 42 | */ 43 | public $buttonOptions = []; 44 | /** 45 | * @var array list of menu items in the dropdown. Each array element can be either an HTML string, 46 | * or an array representing a single menu with the following structure: 47 | * 48 | * - label: string, required, the label of the item link 49 | * - url: string|array, optional, the url of the item link. This will be processed by [[Url::to()]]. 50 | * If not set, the item will be treated as a menu header when the item has no sub-menu. 51 | * - visible: boolean, optional, whether this menu item is visible. Defaults to true. 52 | * - linkOptions: array, optional, the HTML attributes of the item link. 53 | * - options: array, optional, the HTML attributes of the item. 54 | * - items: array, optional, the submenu items. The structure is the same as this property. 55 | * 56 | * To insert divider use `
  • `. 57 | */ 58 | public $items = []; 59 | /** 60 | * @var boolean whether the labels for header items should be HTML-encoded. 61 | */ 62 | public $encodeLabels = true; 63 | 64 | /** 65 | * Initializes the widget. 66 | * If you override this method, make sure you call the parent implementation first. 67 | */ 68 | public function init() 69 | { 70 | parent::init(); 71 | Html::addCssClass($this->options, 'dropdown-content'); 72 | Html::addCssClass($this->buttonOptions, 'btn'); 73 | Html::addCssClass($this->buttonOptions, 'dropdown-button'); 74 | $this->buttonOptions['id'] = $this->id . '-btn'; 75 | $this->buttonOptions['data-activates'] = $this->id; 76 | } 77 | 78 | /** 79 | * Renders the widget. 80 | */ 81 | public function run() 82 | { 83 | MaterializePluginAsset::register($this->getView()); 84 | $this->registerClientEvents(); 85 | $this->getView()->registerJs(" 86 | $('#{$this->id}-btn').dropdown({ 87 | inDuration: 300, 88 | outDuration: 225, 89 | constrain_width: false, // Does not change width of dropdown to that of the activator 90 | hover: false, // Activate on click 91 | alignment: 'left', // Aligns dropdown to left or right edge (works with constrain_width) 92 | gutter: 0, // Spacing from edge 93 | belowOrigin: false // Displays dropdown below the button 94 | }); 95 | "); 96 | if ($this->buttonLabel !== null) { 97 | return Html::tag($this->buttontagName, $this->buttonLabel, $this->buttonOptions) . $this->renderItems($this->items, $this->options); 98 | } else { 99 | return $this->renderItems($this->items, $this->options); 100 | } 101 | } 102 | 103 | /** 104 | * Renders menu items. 105 | * @param array $items the menu items to be rendered 106 | * @param array $options the container HTML attributes 107 | * @return string the rendering result. 108 | * @throws InvalidConfigException if the label option is not specified in one of the items. 109 | */ 110 | protected function renderItems($items, $options = []) 111 | { 112 | $lines = []; 113 | foreach ($items as $i => $item) { 114 | if (isset($item['visible']) && !$item['visible']) { 115 | continue; 116 | } 117 | if (is_string($item)) { 118 | $lines[] = $item; 119 | continue; 120 | } 121 | if (!array_key_exists('label', $item)) { 122 | throw new InvalidConfigException("The 'label' option is required."); 123 | } 124 | $encodeLabel = isset($item['encode']) ? $item['encode'] : $this->encodeLabels; 125 | $label = $encodeLabel ? Html::encode($item['label']) : $item['label']; 126 | $itemOptions = ArrayHelper::getValue($item, 'options', []); 127 | $linkOptions = ArrayHelper::getValue($item, 'linkOptions', []); 128 | $linkOptions['tabindex'] = '-1'; 129 | $url = array_key_exists('url', $item) ? $item['url'] : null; 130 | if (empty($item['items'])) { 131 | if ($url === null) { 132 | $content = $label; 133 | Html::addCssClass($itemOptions, 'dropdown-header'); 134 | } else { 135 | $content = Html::a($label, $url, $linkOptions); 136 | } 137 | } else { 138 | $submenuOptions = $options; 139 | unset($submenuOptions['id']); 140 | $content = Html::a($label, $url === null ? '#' : $url, $linkOptions) 141 | . $this->renderItems($item['items'], $submenuOptions); 142 | Html::addCssClass($itemOptions, 'dropdown-submenu'); 143 | } 144 | 145 | $lines[] = Html::tag('li', $content, $itemOptions); 146 | } 147 | 148 | return Html::tag('ul', implode("\n", $lines), $options); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /Icon.php: -------------------------------------------------------------------------------- 1 | 'grade', 13 | * 'size' => 'large', 14 | * ]); 15 | * ``` 16 | * 17 | * or 18 | * 19 | * ```php 20 | * echo Icon::show('grade', 'large'); 21 | * ``` 22 | * @see http://materializecss.com/icons.html 23 | * @author webmaxx 24 | * @since 2.0 25 | */ 26 | class Icon extends Widget 27 | { 28 | /** 29 | * @var string the tag to use to render the icon 30 | */ 31 | public $tagName = 'i'; 32 | /** 33 | * @var string the icon name 34 | */ 35 | public $name; 36 | /** 37 | * @var string the icon size (tiny, small, medium or large) 38 | */ 39 | public $size = ''; 40 | 41 | /** 42 | * Initializes the widget. 43 | * If you override this method, make sure you call the parent implementation first. 44 | */ 45 | public function init() 46 | { 47 | parent::init(); 48 | $this->clientOptions = false; 49 | Html::addCssClass($this->options, $this->size); 50 | Html::addCssClass($this->options, 'material-icons'); 51 | } 52 | 53 | /** 54 | * Renders the widget. 55 | */ 56 | public function run() 57 | { 58 | return Html::tag($this->tagName, $this->name, $this->options); 59 | } 60 | 61 | /** 62 | * Render icon. 63 | */ 64 | public static function show($name, $size='', $class = '') 65 | { 66 | return self::widget(['name' => $name, 'size' => $size, 'options' => [ 67 | 'class' => $class, 68 | ]]); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 webmaxx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /MaterializeCssAsset.php: -------------------------------------------------------------------------------- 1 | 9 | * @since 2.0 10 | */ 11 | class MaterializeCssAsset extends AssetBundle 12 | { 13 | public $sourcePath = '@bower/materialize/dist'; 14 | public $css = [ 15 | 'css/materialize.css', 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /MaterializeJsAsset.php: -------------------------------------------------------------------------------- 1 | 7 | * @since 2.0 8 | */ 9 | class MaterializeJsAsset extends AssetBundle 10 | { 11 | public $sourcePath = '@bower/materialize/dist'; 12 | public $js = [ 13 | 'js/materialize.js', 14 | ]; 15 | } 16 | -------------------------------------------------------------------------------- /MaterializePluginAsset.php: -------------------------------------------------------------------------------- 1 | 9 | * @since 2.0 10 | */ 11 | class MaterializePluginAsset extends AssetBundle 12 | { 13 | public $sourcePath = '@bower/materialize/dist'; 14 | public $js = [ 15 | ]; 16 | public $depends = [ 17 | 'yii\web\JqueryAsset', 18 | 'webmaxx\materialize\MaterializeCssAsset', 19 | 'webmaxx\materialize\MaterializeJsAsset', 20 | ]; 21 | } 22 | -------------------------------------------------------------------------------- /Nav.php: -------------------------------------------------------------------------------- 1 | [ 16 | * [ 17 | * 'label' => 'Home', 18 | * 'url' => ['site/index'], 19 | * 'linkOptions' => [...], 20 | * ], 21 | * [ 22 | * 'label' => 'Dropdown', 23 | * 'items' => [ 24 | * ['label' => 'Level 1 - Dropdown A', 'url' => '#'], 25 | * '
  • ', 26 | * '', 27 | * ['label' => 'Level 1 - Dropdown B', 'url' => '#'], 28 | * ], 29 | * ], 30 | * ], 31 | * 'options' => ['class' =>'nav-pills'], // set this to nav-tab to get tab-styled navigation 32 | * ]); 33 | * ``` 34 | * @see http://materializecss.com/navbar.html 35 | * @author webmaxx 36 | * @since 2.0 37 | */ 38 | class Nav extends Widget 39 | { 40 | /** 41 | * @var array list of items in the nav widget. Each array element represents a single 42 | * menu item which can be either a string or an array with the following structure: 43 | * 44 | * - label: string, required, the nav item label. 45 | * - url: optional, the item's URL. Defaults to "#". 46 | * - visible: boolean, optional, whether this menu item is visible. Defaults to true. 47 | * - linkOptions: array, optional, the HTML attributes of the item's link. 48 | * - options: array, optional, the HTML attributes of the item container (LI). 49 | * - active: boolean, optional, whether the item should be on active state or not. 50 | * - items: array|string, optional, the configuration array for creating a [[Dropdown]] widget, 51 | * or a string representing the dropdown menu. Note that Bootstrap does not support sub-dropdown menus. 52 | * 53 | * If a menu item is a string, it will be rendered directly without HTML encoding. 54 | */ 55 | public $items = []; 56 | /** 57 | * @var boolean whether the nav items labels should be HTML-encoded. 58 | */ 59 | public $encodeLabels = true; 60 | /** 61 | * @var boolean whether to automatically activate items according to whether their route setting 62 | * matches the currently requested route. 63 | * @see isItemActive 64 | */ 65 | public $activateItems = true; 66 | /** 67 | * @var boolean whether to activate parent menu items when one of the corresponding child menu items is active. 68 | */ 69 | public $activateParents = false; 70 | /** 71 | * @var string the route used to determine if a menu item is active or not. 72 | * If not set, it will use the route of the current request. 73 | * @see params 74 | * @see isItemActive 75 | */ 76 | public $route; 77 | /** 78 | * @var array the parameters used to determine if a menu item is active or not. 79 | * If not set, it will use `$_GET`. 80 | * @see route 81 | * @see isItemActive 82 | */ 83 | public $params; 84 | /** 85 | * @var boolean if true, then its menu used as sidenav for mobile. 86 | */ 87 | public $buttonCollapse = false; 88 | /** 89 | * @var string the text of the button collapse. Note that this is not HTML-encoded. 90 | */ 91 | public $buttonCollapseLabel = ''; 92 | /** 93 | * @var array the HTML attributes of the button collapse. 94 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. 95 | */ 96 | public $buttonCollapseOptions = []; 97 | 98 | /** 99 | * Initializes the widget. 100 | * If you override this method, make sure you call the parent implementation first. 101 | */ 102 | public function init() 103 | { 104 | parent::init(); 105 | if ($this->buttonCollapse) { 106 | Html::addCssClass($this->buttonCollapseOptions, 'button-collapse'); 107 | $this->buttonCollapseOptions['id'] = $this->id . '-button-collapse'; 108 | $this->buttonCollapseOptions['data-activates'] = $this->id; 109 | echo Html::a($this->buttonCollapseLabel, '#', $this->buttonCollapseOptions); 110 | } 111 | if ($this->route === null && Yii::$app->controller !== null) { 112 | $this->route = Yii::$app->controller->getRoute(); 113 | } 114 | if ($this->params === null) { 115 | $this->params = Yii::$app->request->getQueryParams(); 116 | } 117 | Html::addCssClass($this->options, 'nav'); 118 | } 119 | 120 | /** 121 | * Renders the widget. 122 | */ 123 | public function run() 124 | { 125 | MaterializeAsset::register($this->getView()); 126 | if ($this->buttonCollapse) { 127 | MaterializePluginAsset::register($this->getView()); 128 | $this->getView()->registerJs('$("#' . $this->id . '-button-collapse").sideNav();'); 129 | } 130 | return $this->renderItems(); 131 | } 132 | 133 | /** 134 | * Renders widget items. 135 | */ 136 | public function renderItems() 137 | { 138 | $items = []; 139 | foreach ($this->items as $i => $item) { 140 | if (isset($item['visible']) && !$item['visible']) { 141 | continue; 142 | } 143 | $items[] = $this->renderItem($item); 144 | } 145 | 146 | return Html::tag('ul', implode("\n", $items), $this->options); 147 | } 148 | 149 | /** 150 | * Renders a widget's item. 151 | * @param string|array $item the item to render. 152 | * @return string the rendering result. 153 | * @throws InvalidConfigException 154 | */ 155 | public function renderItem($item) 156 | { 157 | if (is_string($item)) { 158 | return $item; 159 | } 160 | if (!isset($item['label'])) { 161 | throw new InvalidConfigException("The 'label' option is required."); 162 | } 163 | $encodeLabel = isset($item['encode']) ? $item['encode'] : $this->encodeLabels; 164 | $label = $encodeLabel ? Html::encode($item['label']) : $item['label']; 165 | $options = ArrayHelper::getValue($item, 'options', []); 166 | $items = ArrayHelper::getValue($item, 'items'); 167 | $url = ArrayHelper::getValue($item, 'url', '#'); 168 | $linkOptions = ArrayHelper::getValue($item, 'linkOptions', []); 169 | 170 | if (isset($item['active'])) { 171 | $active = ArrayHelper::remove($item, 'active', false); 172 | } else { 173 | $active = $this->isItemActive($item); 174 | } 175 | 176 | if ($items !== null) { 177 | $dropdownId = uniqid($this->id . '-dropdown_'); 178 | Html::addCssClass($options, 'dropdown'); 179 | Html::addCssClass($linkOptions, 'dropdown-button'); 180 | $linkOptions['id'] = $dropdownId . '-btn'; 181 | $linkOptions['data-activates'] = $dropdownId; 182 | $label .= ' ' . Icon::widget(['name' => 'navigation-arrow-drop-down right']); 183 | if (is_array($items)) { 184 | if ($this->activateItems) { 185 | $items = $this->isChildActive($items, $active); 186 | } 187 | $items = $this->renderDropdown($items, $item, $dropdownId); 188 | } 189 | } 190 | 191 | if ($this->activateItems && $active) { 192 | Html::addCssClass($options, 'active'); 193 | } 194 | 195 | return Html::tag('li', Html::a($label, $url, $linkOptions) . $items, $options); 196 | } 197 | 198 | /** 199 | * Renders the given items as a dropdown. 200 | * This method is called to create sub-menus. 201 | * @param array $items the given items. Please refer to [[Dropdown::items]] for the array structure. 202 | * @param array $parentItem the parent item information. Please refer to [[items]] for the structure of this array. 203 | * @return string the rendering result. 204 | * @since 2.0.1 205 | */ 206 | protected function renderDropdown($items, $parentItem, $dropdownId) 207 | { 208 | return Dropdown::widget([ 209 | 'id' => $dropdownId, 210 | 'buttonLabel' => null, 211 | 'items' => $items, 212 | 'encodeLabels' => $this->encodeLabels, 213 | 'clientOptions' => false, 214 | 'view' => $this->getView(), 215 | ]); 216 | } 217 | 218 | /** 219 | * Check to see if a child item is active optionally activating the parent. 220 | * @param array $items @see items 221 | * @param boolean $active should the parent be active too 222 | * @return array @see items 223 | */ 224 | protected function isChildActive($items, &$active) 225 | { 226 | foreach ($items as $i => $child) { 227 | if (ArrayHelper::remove($items[$i], 'active', false) || $this->isItemActive($child)) { 228 | Html::addCssClass($items[$i]['options'], 'active'); 229 | if ($this->activateParents) { 230 | $active = true; 231 | } 232 | } 233 | } 234 | return $items; 235 | } 236 | 237 | /** 238 | * Checks whether a menu item is active. 239 | * This is done by checking if [[route]] and [[params]] match that specified in the `url` option of the menu item. 240 | * When the `url` option of a menu item is specified in terms of an array, its first element is treated 241 | * as the route for the item and the rest of the elements are the associated parameters. 242 | * Only when its route and parameters match [[route]] and [[params]], respectively, will a menu item 243 | * be considered active. 244 | * @param array $item the menu item to be checked 245 | * @return boolean whether the menu item is active 246 | */ 247 | protected function isItemActive($item) 248 | { 249 | if (isset($item['url']) && is_array($item['url']) && isset($item['url'][0])) { 250 | $route = $item['url'][0]; 251 | if ($route[0] !== '/' && Yii::$app->controller) { 252 | $route = Yii::$app->controller->module->getUniqueId() . '/' . $route; 253 | } 254 | if (ltrim($route, '/') !== $this->route) { 255 | return false; 256 | } 257 | unset($item['url']['#']); 258 | if (count($item['url']) > 1) { 259 | foreach (array_splice($item['url'], 1) as $name => $value) { 260 | if ($value !== null && (!isset($this->params[$name]) || $this->params[$name] != $value)) { 261 | return false; 262 | } 263 | } 264 | } 265 | 266 | return true; 267 | } 268 | 269 | return false; 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /NavBar.php: -------------------------------------------------------------------------------- 1 | 'NavBar Test']); 19 | * echo Nav::widget([ 20 | * 'items' => [ 21 | * ['label' => 'Home', 'url' => ['/site/index']], 22 | * ['label' => 'About', 'url' => ['/site/about']], 23 | * ], 24 | * ]); 25 | * NavBar::end(); 26 | * ``` 27 | * @see http://materializecss.com/navbar.html 28 | * @author webmaxx 29 | * @since 2.0 30 | */ 31 | class NavBar extends Widget 32 | { 33 | /** 34 | * @var array the HTML attributes for the widget container tag. The following special options are recognized: 35 | * 36 | * - tag: string, defaults to "nav", the name of the container tag. 37 | * 38 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. 39 | */ 40 | public $options = []; 41 | /** 42 | * @var string|boolean the text of the brand of false if it's not used. Note that this is not HTML-encoded. 43 | */ 44 | public $brandLabel = false; 45 | /** 46 | * @param array|string|boolean $url the URL for the brand's hyperlink tag. This parameter will be processed by [[Url::to()]] 47 | * and will be used for the "href" attribute of the brand link. Default value is false that means 48 | * [[\yii\web\Application::homeUrl]] will be used. 49 | */ 50 | public $brandUrl = false; 51 | /** 52 | * @var array the HTML attributes of the brand link. 53 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. 54 | */ 55 | public $brandOptions = []; 56 | /** 57 | * @var boolean if true, then navbar fixed on scroll 58 | */ 59 | public $fixed = false; 60 | /** 61 | * @var array the HTML attributes of the fixed container. 62 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. 63 | */ 64 | public $fixedContainerOptions = []; 65 | /** 66 | * @var array the HTML attributes of the wrapper container. 67 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. 68 | */ 69 | public $wraperContainerOptions = []; 70 | 71 | /** 72 | * Initializes the widget. 73 | */ 74 | public function init() 75 | { 76 | parent::init(); 77 | $this->clientOptions = false; 78 | if ($this->fixed) { 79 | if (!isset($this->fixedContainerOptions['class'])) { 80 | Html::addCssClass($this->fixedContainerOptions, 'navbar-fixed'); 81 | } 82 | echo Html::beginTag('div', $this->fixedContainerOptions); 83 | } 84 | Html::addCssClass($this->brandOptions, 'brand-logo'); 85 | $options = $this->options; 86 | $tag = ArrayHelper::remove($options, 'tag', 'nav'); 87 | echo Html::beginTag($tag, $options); 88 | if (!isset($this->wraperContainerOptions['class'])) { 89 | Html::addCssClass($this->wraperContainerOptions, 'nav-wrapper'); 90 | } 91 | echo Html::beginTag('div', $this->wraperContainerOptions); 92 | if ($this->brandLabel !== false) { 93 | Html::addCssClass($this->brandOptions, 'brand-logo'); 94 | echo Html::a($this->brandLabel, $this->brandUrl === false ? Yii::$app->homeUrl : $this->brandUrl, $this->brandOptions); 95 | } 96 | } 97 | 98 | /** 99 | * Renders the widget. 100 | */ 101 | public function run() 102 | { 103 | //echo Html::endTag('div'); 104 | $tag = ArrayHelper::remove($this->options, 'tag', 'nav'); 105 | echo Html::endTag($tag, $this->options); 106 | if ($this->fixed) { 107 | echo Html::endTag('div'); 108 | } 109 | MaterializePluginAsset::register($this->getView()); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Preloader.php: -------------------------------------------------------------------------------- 1 | 'red' // 'red', 'blue', 'yellow', 'green' 13 | * ]); 14 | * ``` 15 | * or 16 | * 17 | * ```php 18 | * echo Preloader::widget([ 19 | * 'color' => ['red', 'blue', 'yellow', 'green'] 20 | * ]); 21 | * ``` 22 | * @see http://materializecss.com/preloader.html 23 | * @author webmaxx 24 | * @since 2.0 25 | */ 26 | class Preloader extends Widget 27 | { 28 | /** 29 | * @var string the tag to use to render the button 30 | */ 31 | public $color = 'blue'; 32 | /** 33 | * @var string default css class for button 34 | */ 35 | public $defaultClass = 'preloader-wrapper active'; 36 | 37 | /** 38 | * Initializes the widget. 39 | * If you override this method, make sure you call the parent implementation first. 40 | */ 41 | public function init() 42 | { 43 | parent::init(); 44 | $this->clientOptions = false; 45 | if ($this->defaultClass) 46 | Html::addCssClass($this->options, $this->defaultClass); 47 | } 48 | 49 | /** 50 | * Renders the widget. 51 | */ 52 | public function run() 53 | { 54 | MaterializeAsset::register($this->getView()); 55 | return Html::tag('div', $this->renderItems(), $this->options); 56 | } 57 | 58 | /** 59 | * Generates the preloader items that compound the group as specified on [[preloader]]. 60 | * @return string the rendering result. 61 | */ 62 | protected function renderItems() 63 | { 64 | $items = []; 65 | if (is_array($this->color)) { 66 | $items = []; 67 | foreach ($this->color as $color) { 68 | $items[] = $this->renderItem($color); 69 | } 70 | } else { 71 | $items[] = $this->renderItem($this->color . '-only'); 72 | } 73 | 74 | return implode("\n", $items); 75 | } 76 | 77 | /** 78 | * Generates the preloader item. 79 | * @return string the rendering result. 80 | */ 81 | protected function renderItem($color) 82 | { 83 | return Html::tag('div', ( 84 | Html::tag('div', Html::tag('div', '', ['class' => 'circle']), ['class' => 'circle-clipper left']) 85 | . Html::tag('div', Html::tag('div', '', ['class' => 'circle']), ['class' => 'gap-patch']) 86 | . Html::tag('div', Html::tag('div', '', ['class' => 'circle']), ['class' => 'circle-clipper right']) 87 | ), ['class' => 'spinner-layer spinner-' . $color]); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Progress.php: -------------------------------------------------------------------------------- 1 | 70, 13 | * 'options' => ['class' => 'red'], 14 | * ]); 15 | * ``` 16 | * or 17 | * 18 | * ```php 19 | * echo Progress::widget([ 20 | * 'determinate' => false, 21 | * 'options' => ['class' => 'red'], 22 | * ]); 23 | * ``` 24 | * @see http://materializecss.com/preloader.html 25 | * @author webmaxx 26 | * @since 2.0 27 | */ 28 | class Progress extends Widget 29 | { 30 | /** 31 | * @var integer the percent of progress 32 | */ 33 | public $percent = 0; 34 | /** 35 | * @var bool the determinate or indeterminate progress 36 | */ 37 | public $determinate = true; 38 | /** 39 | * @var array the HTML attributes for the widget container tag. 40 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. 41 | */ 42 | public $wrapOptions = []; 43 | 44 | /** 45 | * Initializes the widget. 46 | * If you override this method, make sure you call the parent implementation first. 47 | */ 48 | public function init() 49 | { 50 | parent::init(); 51 | $this->clientOptions = false; 52 | Html::addCssClass($this->wrapOptions, 'progress'); 53 | if ($this->determinate) 54 | Html::addCssClass($this->options, 'determinate'); 55 | else 56 | Html::addCssClass($this->options, 'indeterminate'); 57 | 58 | if ($this->percent) { 59 | if (!isset($this->options['style'])) { 60 | $this->options['style'] = 'width: ' . $this->percent . '%'; 61 | } else { 62 | $this->options['style'] = explode(';', trim($this->options['style'], ';')); 63 | $this->options['style'][] = 'width: ' . $this->percent . '%;'; 64 | $this->options['style'] = implode(';', $this->options['style']); 65 | } 66 | } 67 | } 68 | 69 | /** 70 | * Renders the widget. 71 | */ 72 | public function run() 73 | { 74 | return Html::tag('div', Html::tag('div', '', $this->options), $this->wrapOptions); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Materialize Extension for Yii 2 2 | =============================== 3 | 4 | --- 5 | 6 | > ### Note! 7 | > 8 | > This extension in dev mode. 9 | 10 | --- 11 | 12 | This is the Materialize extension for Yii 2. It encapsulates [Materialize](http://materializecss.com/) components 13 | and plugins in terms of Yii widgets, and thus makes using Materialize components/plugins 14 | in Yii applications extremely easy. 15 | 16 | For license information check the [LICENSE](LICENSE.md)-file. 17 | 18 | Installation 19 | ------------ 20 | 21 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 22 | 23 | Either run 24 | 25 | ``` 26 | php composer.phar require --prefer-dist webmaxx/yii2-materialize 27 | ``` 28 | 29 | or add 30 | 31 | ``` 32 | "webmaxx/yii2-materialize": "dev-master" 33 | ``` 34 | 35 | to the require section of your `composer.json` file. 36 | 37 | Usage 38 | ---- 39 | 40 | For example, the following 41 | single line of code in a view file would render a Materialize Progress plugin: 42 | 43 | ```php 44 | 70]) ?> 45 | ``` 46 | -------------------------------------------------------------------------------- /Widget.php: -------------------------------------------------------------------------------- 1 | 10 | * @since 2.0 11 | */ 12 | class Widget extends \yii\base\Widget 13 | { 14 | /** 15 | * @var array the HTML attributes for the widget container tag. 16 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. 17 | */ 18 | public $options = []; 19 | /** 20 | * @var array the options for the underlying Materialize JS plugin. 21 | * Please refer to the corresponding Materialize plugin Web page for possible options. 22 | * For example, [this page](http://materializecss.com/modals.html) shows 23 | * how to use the "Modal" plugin and the supported options (e.g. "remote"). 24 | */ 25 | public $clientOptions = []; 26 | /** 27 | * @var array the event handlers for the underlying Materialize JS plugin. 28 | * Please refer to the corresponding Materialize plugin Web page for possible events. 29 | * For example, [this page](http://materializecss.com/modals.html) shows 30 | * how to use the "Modal" plugin and the supported events (e.g. "shown"). 31 | */ 32 | public $clientEvents = []; 33 | 34 | 35 | /** 36 | * Initializes the widget. 37 | * This method will register the materialize asset bundle. If you override this method, 38 | * make sure you call the parent implementation first. 39 | */ 40 | public function init() 41 | { 42 | parent::init(); 43 | if (!isset($this->options['id'])) { 44 | $this->options['id'] = $this->getId(); 45 | } 46 | } 47 | 48 | /** 49 | * Registers a specific Materialize plugin and the related events 50 | * @param string $name the name of the Materialize plugin 51 | */ 52 | protected function registerPlugin($name) 53 | { 54 | $view = $this->getView(); 55 | 56 | MaterializePluginAsset::register($view); 57 | 58 | $id = $this->options['id']; 59 | 60 | if ($this->clientOptions !== false) { 61 | $options = empty($this->clientOptions) ? '' : Json::encode($this->clientOptions); 62 | $js = "jQuery('#$id').$name($options);"; 63 | $view->registerJs($js); 64 | } 65 | 66 | $this->registerClientEvents(); 67 | } 68 | 69 | /** 70 | * Registers JS event handlers that are listed in [[clientEvents]]. 71 | * @since 2.0.2 72 | */ 73 | protected function registerClientEvents() 74 | { 75 | if (!empty($this->clientEvents)) { 76 | $id = $this->options['id']; 77 | $js = []; 78 | foreach ($this->clientEvents as $event => $handler) { 79 | $js[] = "jQuery('#$id').on('$event', $handler);"; 80 | } 81 | $this->getView()->registerJs(implode("\n", $js)); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webmaxx/yii2-materialize", 3 | "description": "The Materialize extension for the Yii framework", 4 | "keywords": ["yii2", "materialize"], 5 | "type": "yii2-extension", 6 | "license": "MIT", 7 | "support": { 8 | "issues": "https://github.com/webmaxx/yii2-materialize/issues", 9 | "source": "https://github.com/webmaxx/yii2-materialize" 10 | }, 11 | "authors": [ 12 | { 13 | "name": "webmaxx", 14 | "email": "webmaxx@webmaxx.name" 15 | } 16 | ], 17 | "minimum-stability": "dev", 18 | "require": { 19 | "yiisoft/yii2": "*", 20 | "bower-asset/materialize": "@stable" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "webmaxx\\materialize\\": "" 25 | } 26 | }, 27 | "extra": { 28 | "asset-installer-paths": { 29 | "npm-asset-library": "vendor/npm", 30 | "bower-asset-library": "vendor/bower" 31 | } 32 | } 33 | } 34 | --------------------------------------------------------------------------------