NavBar   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 372
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 31
eloc 148
c 2
b 0
f 0
dl 0
loc 372
ccs 152
cts 152
cp 1
rs 9.92

25 Methods

Rating   Name   Duplication   Size   Complexity  
A brandImage() 0 5 1
A autoIdPrefix() 0 5 1
A brandAttributes() 0 5 1
A render() 0 3 1
A renderNavBarBurger() 0 26 2
A buttonLinkAriaLabelText() 0 5 1
A buttonLinkAriaExpanded() 0 5 1
A buttonLinkContent() 0 5 1
A brandTextAttributes() 0 5 1
A brandImageAttributes() 0 5 1
A itemCssClass() 0 5 1
A buttonLinkRole() 0 5 1
A begin() 0 4 1
A burgerAttributes() 0 5 1
A role() 0 5 1
A renderNavBar() 0 13 2
A id() 0 5 1
A ariaLabel() 0 5 1
A brandUrl() 0 5 1
A cssClass() 0 5 1
A burgerCssClass() 0 5 1
A attributes() 0 5 1
A renderNavBarBrand() 0 49 5
A brandText() 0 5 1
A brandCssClass() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Bulma;
6
7
use Yiisoft\Html\Html;
8
use Yiisoft\Html\Tag\A;
9
use Yiisoft\Html\Tag\Div;
10
use Yiisoft\Html\Tag\Img;
11
use Yiisoft\Html\Tag\Span;
12
use Yiisoft\Widget\Widget;
13
14
/**
15
 * NavBar renders a navbar HTML component.
16
 *
17
 * Any content enclosed between the {@see begin()} and {@see end()} calls of NavBar is treated as the content of the
18
 * navbar. You may use widgets such as {@see Nav} to build up such content. For example,
19
 *
20
 * @link https://bulma.io/documentation/components/navbar/
21
 */
22
final class NavBar extends Widget
23
{
24
    private string $ariaLabel = 'main navigation';
25
    private array $attributes = [];
26
    private string $autoIdPrefix = 'w';
27
    private array $brandAttributes = [];
28
    private string $brandImage = '';
29
    private array $brandImageAttributes = [];
30
    private string $brandText = '';
31
    private array $brandTextAttributes = [];
32
    private string $brandUrl = '/';
33
    private string $brandCssClass = 'navbar-brand';
34
    private array $burgerAttributes = [];
35
    private string $burgerCssClass = 'navbar-burger';
36
    private string $buttonLinkAriaExpanded = 'false';
37
    private string $buttonLinkAriaLabelText = 'menu';
38
    private string $buttonLinkContent = '';
39
    private string $buttonLinkRole = 'button';
40
    private string $cssClass = 'navbar';
41
    private string $itemCssClass = 'navbar-item';
42
    private string $role = 'navigation';
43
44
    /**
45
     * Returns a new instance with the specified `aria-label` attribute for the current element.
46
     */
47 2
    public function ariaLabel(string $value): self
48
    {
49 2
        $new = clone $this;
50 2
        $new->ariaLabel = $value;
51 2
        return $new;
52
    }
53
54
    /**
55
     * Returns a new instance with the specified HTML attributes for widget.
56
     *
57
     * @param array $values Attribute values indexed by attribute names.
58
     *
59
     * {@see Html::renderTagAttributes()} For details on how attributes are being rendered.
60
     */
61 1
    public function attributes(array $values): self
62
    {
63 1
        $new = clone $this;
64 1
        $new->attributes = $values;
65 1
        return $new;
66
    }
67
68
    /**
69
     * Returns a new instance with the specified prefix to the automatically generated widget IDs.
70
     *
71
     * @param string $value The prefix to the automatically generated widget IDs.
72
     */
73 1
    public function autoIdPrefix(string $value): self
74
    {
75 1
        $new = clone $this;
76 1
        $new->autoIdPrefix = $value;
77 1
        return $new;
78
    }
79
80 18
    public function begin(): string
81
    {
82 18
        parent::begin();
83 18
        return $this->renderNavBar();
84
    }
85
86
    /**
87
     * Returns a new instance with the specified HTML attributes for the navbar brand.
88
     *
89
     * @param array $values Attribute values indexed by attribute names.
90
     *
91
     * {@see Html::renderTagAttributes()} For details on how attributes are being rendered.
92
     */
93 2
    public function brandAttributes(array $values): self
94
    {
95 2
        $new = clone $this;
96 2
        $new->brandAttributes = $values;
97 2
        return $new;
98
    }
99
100
    /**
101
     * Returns a new instance with the specified the CSS class of the brand.
102
     *
103
     * @param string $value The CSS class.
104
     */
105 2
    public function brandCssClass(string $value): self
106
    {
107 2
        $new = clone $this;
108 2
        $new->brandCssClass = $value;
109 2
        return $new;
110
    }
111
112
    /**
113
     * Returns a new instance with the specified src of the brand image, empty if it's not used.
114
     *
115
     * Note that this param will override `$this->brandText` param.
116
     *
117
     * @param string $value The src of the brand image.
118
     */
119 3
    public function brandImage(string $value): self
120
    {
121 3
        $new = clone $this;
122 3
        $new->brandImage = $value;
123 3
        return $new;
124
    }
125
126
    /**
127
     * Returns a new instance with the specified HTML attributes for the brand image.
128
     *
129
     * @param array $values Attribute values indexed by attribute names.
130
     *
131
     * {@see Html::renderTagAttributes()} For details on how attributes are being rendered.
132
     */
133 3
    public function brandImageAttributes(array $values): self
134
    {
135 3
        $new = clone $this;
136 3
        $new->brandImageAttributes = $values;
137 3
        return $new;
138
    }
139
140
    /**
141
     * Returns a new instance with the specified the text of the brand or empty if it's not used. Note that this is not
142
     * HTML-encoded.
143
     *
144
     * @param string $value The text of the brand.
145
     */
146 5
    public function brandText(string $value): self
147
    {
148 5
        $new = clone $this;
149 5
        $new->brandText = $value;
150 5
        return $new;
151
    }
152
153
    /**
154
     * Returns a new instance with the specified HTML attributes for the brand text.
155
     *
156
     * @param array $values Attribute values indexed by attribute names.
157
     *
158
     * {@see Html::renderTagAttributes()} For details on how attributes are being rendered.
159
     */
160 2
    public function brandTextAttributes(array $values): self
161
    {
162 2
        $new = clone $this;
163 2
        $new->brandTextAttributes = $values;
164 2
        return $new;
165
    }
166
167
    /**
168
     * Returns a new instance with the specified the URL for the brand's hyperlink tag and will be used for the "href"
169
     * attribute of the brand link. Default value is "/". You may set it to empty string if you want no link at all.
170
     */
171 4
    public function brandUrl(string $value): self
172
    {
173 4
        $new = clone $this;
174 4
        $new->brandUrl = $value;
175 4
        return $new;
176
    }
177
178
    /**
179
     * Returns a new instance with the specified HTML attributes for the burger.
180
     *
181
     * @param array $values Attribute values indexed by attribute names.
182
     *
183
     * {@see Html::renderTagAttributes()} For details on how attributes are being rendered.
184
     */
185 2
    public function burgerAttributes(array $values): self
186
    {
187 2
        $new = clone $this;
188 2
        $new->burgerAttributes = $values;
189 2
        return $new;
190
    }
191
192
    /**
193
     * Returns a new instance with the specified the CSS class of the burger.
194
     *
195
     * @param string $value The CSS class.
196
     */
197 2
    public function burgerCssClass(string $value): self
198
    {
199 2
        $new = clone $this;
200 2
        $new->burgerCssClass = $value;
201 2
        return $new;
202
    }
203
204
    /**
205
     * Returns a new instance with the specified the ARIA expanded attribute of the button link.
206
     */
207 2
    public function buttonLinkAriaExpanded(string $value): self
208
    {
209 2
        $new = clone $this;
210 2
        $new->buttonLinkAriaExpanded = $value;
211 2
        return $new;
212
    }
213
214
    /**
215
     * Returns a new instance with the specified HTML attributes for the ARIA label text of the button link.
216
     */
217 2
    public function buttonLinkAriaLabelText(string $value): self
218
    {
219 2
        $new = clone $this;
220 2
        $new->buttonLinkAriaLabelText = $value;
221 2
        return $new;
222
    }
223
224
    /**
225
     * Returns a new instance with the specified the content of the button link.
226
     */
227 2
    public function buttonLinkContent(string $value): self
228
    {
229 2
        $new = clone $this;
230 2
        $new->buttonLinkContent = $value;
231 2
        return $new;
232
    }
233
234
    /**
235
     * Returns a new instance with the specified the role of the button link.
236
     */
237 2
    public function buttonLinkRole(string $value): self
238
    {
239 2
        $new = clone $this;
240 2
        $new->buttonLinkRole = $value;
241 2
        return $new;
242
    }
243
244
    /**
245
     * Returns a new instance with the specified the CSS class of the navbar.
246
     *
247
     * @param string $value The CSS class.
248
     */
249 2
    public function cssClass(string $value): self
250
    {
251 2
        $new = clone $this;
252 2
        $new->cssClass = $value;
253 2
        return $new;
254
    }
255
256
    /**
257
     * Returns a new instance with the specified ID of the widget.
258
     *
259
     * @param string $value The ID of the widget.
260
     */
261 2
    public function id(string $value): self
262
    {
263 2
        $new = clone $this;
264 2
        $new->attributes['id'] = $value;
265 2
        return $new;
266
    }
267
268
    /**
269
     * Returns a new instance with the specified the CSS class of the items navbar.
270
     *
271
     * @param string $value The CSS class.
272
     */
273 2
    public function itemCssClass(string $value): self
274
    {
275 2
        $new = clone $this;
276 2
        $new->itemCssClass = $value;
277 2
        return $new;
278
    }
279
280
    /**
281
     * Returns a new instance with the specified the role of the navbar.
282
     */
283 2
    public function role(string $value): self
284
    {
285 2
        $new = clone $this;
286 2
        $new->role = $value;
287 2
        return $new;
288
    }
289
290 18
    public function render(): string
291
    {
292 18
        return Html::closeTag('nav');
293
    }
294
295 18
    private function renderNavBar(): string
296
    {
297 18
        $attributes = $this->attributes;
298 18
        Html::addCssClass($attributes, $this->cssClass);
299
300 18
        if (!isset($attributes['id'])) {
301 17
            $attributes['id'] = Html::generateId($this->autoIdPrefix) . '-navbar';
302
        }
303
304 18
        $attributes['aria-label'] = $this->ariaLabel;
305 18
        $attributes['role'] = $this->role;
306
307 18
        return Html::openTag('nav', $attributes) . PHP_EOL . $this->renderNavBarBrand() . PHP_EOL;
308
    }
309
310 18
    private function renderNavBarBrand(): string
311
    {
312 18
        $brand = '';
313 18
        $brandImage = '';
314
315 18
        if ($this->brandImage !== '') {
316 2
            $brandImage = Img::tag()
317 2
                ->attributes($this->brandImageAttributes)
318 2
                ->url($this->brandImage)
319 2
                ->render();
320 2
            $brand = PHP_EOL . A::tag()
321 2
                ->class($this->itemCssClass)
322 2
                ->content($brandImage)
323 2
                ->encode(false)
324 2
                ->url($this->brandUrl)
325 2
                ->render();
326
        }
327
328 18
        if ($this->brandText !== '') {
329 4
            $brandText = $this->brandText;
330
331 4
            if ($brandImage !== '') {
332 1
                $brandText = $brandImage . $this->brandText;
333
            }
334
335 4
            if (empty($this->brandUrl)) {
336 1
                $brand = PHP_EOL . Span::tag()
337 1
                    ->addAttributes($this->brandTextAttributes)
338 1
                    ->addClass($this->itemCssClass)
339 1
                    ->content($brandText)
340 1
                    ->render();
341
            } else {
342 3
                $brand = PHP_EOL . A::tag()
343 3
                    ->addClass($this->itemCssClass)
344 3
                    ->content($brandText)
345 3
                    ->encode(false)
346 3
                    ->url($this->brandUrl)
347 3
                    ->render();
348
            }
349
        }
350
351 18
        $brand .= $this->renderNavBarBurger();
352
353 18
        return Div::tag()
354 18
            ->addAttributes($this->brandAttributes)
355 18
            ->addClass($this->brandCssClass)
356 18
            ->content($brand)
357 18
            ->encode(false)
358 18
            ->render();
359
    }
360
361
    /**
362
     * Renders collapsible toggle button.
363
     *
364
     * @return string the rendering navbar burger link button.
365
     *
366
     * @link https://bulma.io/documentation/components/navbar/#navbar-burger
367
     */
368 18
    private function renderNavBarBurger(): string
369
    {
370 18
        $burgerAttributes = $this->burgerAttributes;
371 18
        if ($this->buttonLinkContent === '') {
372 17
            $this->buttonLinkContent = PHP_EOL .
373 17
                Span::tag()
374 17
                    ->attributes(['aria-hidden' => 'true'])
375 17
                    ->render() . PHP_EOL .
376 17
                Span::tag()
377 17
                    ->attributes(['aria-hidden' => 'true'])
378 17
                    ->render() . PHP_EOL .
379 17
                Span::tag()
380 17
                    ->attributes(['aria-hidden' => 'true'])
381 17
                    ->render() . PHP_EOL;
382
        }
383
384 18
        $burgerAttributes['aria-expanded'] = $this->buttonLinkAriaExpanded;
385 18
        $burgerAttributes['aria-label'] = $this->buttonLinkAriaLabelText;
386 18
        $burgerAttributes['role'] = $this->buttonLinkRole;
387
388 18
        return PHP_EOL . A::tag()
389 18
            ->addAttributes($burgerAttributes)
390 18
            ->addClass($this->burgerCssClass)
391 18
            ->content($this->buttonLinkContent)
392 18
            ->encode(false)
393 18
            ->render() . PHP_EOL;
394
    }
395
}
396