Passed
Pull Request — master (#79)
by Wilmer
02:24
created

NavBar::render()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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
     * @param string $value
48
     *
49
     * @return self
50
     */
51 2
    public function ariaLabel(string $value): self
52
    {
53 2
        $new = clone $this;
54 2
        $new->ariaLabel = $value;
55 2
        return $new;
56
    }
57
58
    /**
59
     * Returns a new instance with the specified HTML attributes for widget.
60
     *
61
     * @param array $values Attribute values indexed by attribute names.
62
     *
63
     * @return self
64
     *
65
     * {@see Html::renderTagAttributes()} For details on how attributes are being rendered.
66
     */
67 1
    public function attributes(array $values): self
68
    {
69 1
        $new = clone $this;
70 1
        $new->attributes = $values;
71 1
        return $new;
72
    }
73
74
    /**
75
     * Returns a new instance with the specified prefix to the automatically generated widget IDs.
76
     *
77
     * @param string $value The prefix to the automatically generated widget IDs.
78
     *
79
     * @return self
80
     */
81 1
    public function autoIdPrefix(string $value): self
82
    {
83 1
        $new = clone $this;
84 1
        $new->autoIdPrefix = $value;
85 1
        return $new;
86
    }
87
88 18
    public function begin(): string
89
    {
90 18
        parent::begin();
91 18
        return $this->renderNavBar();
92
    }
93
94
    /**
95
     * Returns a new instance with the specified HTML attributes for the navbar brand.
96
     *
97
     * @param array $values Attribute values indexed by attribute names.
98
     *
99
     * @return self
100
     *
101
     * {@see Html::renderTagAttributes()} For details on how attributes are being rendered.
102
     */
103 2
    public function brandAttributes(array $values): self
104
    {
105 2
        $new = clone $this;
106 2
        $new->brandAttributes = $values;
107 2
        return $new;
108
    }
109
110
    /**
111
     * Returns a new instance with the specified the CSS class of the brand.
112
     *
113
     * @param string $value The CSS class.
114
     *
115
     * @return self
116
     */
117 2
    public function brandCssClass(string $value): self
118
    {
119 2
        $new = clone $this;
120 2
        $new->brandCssClass = $value;
121 2
        return $new;
122
    }
123
124
    /**
125
     * Returns a new instance with the specified src of the brand image, empty if it's not used.
126
     *
127
     * Note that this param will override `$this->brandText` param.
128
     *
129
     * @param string $value The src of the brand image.
130
     *
131
     * @return self
132
     */
133 3
    public function brandImage(string $value): self
134
    {
135 3
        $new = clone $this;
136 3
        $new->brandImage = $value;
137 3
        return $new;
138
    }
139
140
    /**
141
     * Returns a new instance with the specified HTML attributes for the brand image.
142
     *
143
     * @param array $values Attribute values indexed by attribute names.
144
     *
145
     * @return self
146
     *
147
     * {@see Html::renderTagAttributes()} For details on how attributes are being rendered.
148
     */
149 3
    public function brandImageAttributes(array $values): self
150
    {
151 3
        $new = clone $this;
152 3
        $new->brandImageAttributes = $values;
153 3
        return $new;
154
    }
155
156
    /**
157
     * Returns a new instance with the specified the text of the brand or empty if it's not used. Note that this is not
158
     * HTML-encoded.
159
     *
160
     * @param string $value The text of the brand.
161
     *
162
     * @return self
163
     */
164 5
    public function brandText(string $value): self
165
    {
166 5
        $new = clone $this;
167 5
        $new->brandText = $value;
168 5
        return $new;
169
    }
170
171
    /**
172
     * Returns a new instance with the specified HTML attributes for the brand text.
173
     *
174
     * @param array $values Attribute values indexed by attribute names.
175
     *
176
     * @return self
177
     *
178
     * {@see Html::renderTagAttributes()} For details on how attributes are being rendered.
179
     */
180 2
    public function brandTextAttributes(array $values): self
181
    {
182 2
        $new = clone $this;
183 2
        $new->brandTextAttributes = $values;
184 2
        return $new;
185
    }
186
187
    /**
188
     * Returns a new instance with the specified the URL for the brand's hyperlink tag and will be used for the "href"
189
     * attribute of the brand link. Default value is "/". You may set it to empty string if you want no link at all.
190
     *
191
     * @param string $value
192
     *
193
     * @return self
194
     */
195 4
    public function brandUrl(string $value): self
196
    {
197 4
        $new = clone $this;
198 4
        $new->brandUrl = $value;
199 4
        return $new;
200
    }
201
202
    /**
203
     * Returns a new instance with the specified HTML attributes for the burger.
204
     *
205
     * @param array $values Attribute values indexed by attribute names.
206
     *
207
     * @return self
208
     *
209
     * {@see Html::renderTagAttributes()} For details on how attributes are being rendered.
210
     */
211 2
    public function burgerAttributes(array $values): self
212
    {
213 2
        $new = clone $this;
214 2
        $new->burgerAttributes = $values;
215 2
        return $new;
216
    }
217
218
    /**
219
     * Returns a new instance with the specified the CSS class of the burger.
220
     *
221
     * @param string $value The CSS class.
222
     *
223
     * @return self
224
     */
225 2
    public function burgerCssClass(string $value): self
226
    {
227 2
        $new = clone $this;
228 2
        $new->burgerCssClass = $value;
229 2
        return $new;
230
    }
231
232
    /**
233
     * Returns a new instance with the specified the ARIA expanded attribute of the button link.
234
     *
235
     * @param string $value
236
     *
237
     * @return self
238
     */
239 2
    public function buttonLinkAriaExpanded(string $value): self
240
    {
241 2
        $new = clone $this;
242 2
        $new->buttonLinkAriaExpanded = $value;
243 2
        return $new;
244
    }
245
246
    /**
247
     * Returns a new instance with the specified HTML attributes for the ARIA label text of the button link.
248
     *
249
     * @param string $value
250
     *
251
     * @return self
252
     */
253 2
    public function buttonLinkAriaLabelText(string $value): self
254
    {
255 2
        $new = clone $this;
256 2
        $new->buttonLinkAriaLabelText = $value;
257 2
        return $new;
258
    }
259
260
    /**
261
     * Returns a new instance with the specified the content of the button link.
262
     *
263
     * @param string $value
264
     *
265
     * @return self
266
     */
267 2
    public function buttonLinkContent(string $value): self
268
    {
269 2
        $new = clone $this;
270 2
        $new->buttonLinkContent = $value;
271 2
        return $new;
272
    }
273
274
    /**
275
     * Returns a new instance with the specified the role of the button link.
276
     *
277
     * @param string $value
278
     *
279
     * @return self
280
     */
281 2
    public function buttonLinkRole(string $value): self
282
    {
283 2
        $new = clone $this;
284 2
        $new->buttonLinkRole = $value;
285 2
        return $new;
286
    }
287
288
    /**
289
     * Returns a new instance with the specified the CSS class of the navbar.
290
     *
291
     * @param string $value The CSS class.
292
     *
293
     * @return self
294
     */
295 2
    public function cssClass(string $value): self
296
    {
297 2
        $new = clone $this;
298 2
        $new->cssClass = $value;
299 2
        return $new;
300
    }
301
302
    /**
303
     * Returns a new instance with the specified ID of the widget.
304
     *
305
     * @param string $value The ID of the widget.
306
     *
307
     * @return self
308
     */
309 2
    public function id(string $value): self
310
    {
311 2
        $new = clone $this;
312 2
        $new->attributes['id'] = $value;
313 2
        return $new;
314
    }
315
316
    /**
317
     * Returns a new instance with the specified the CSS class of the items navbar.
318
     *
319
     * @param string $value The CSS class.
320
     *
321
     * @return self
322
     */
323 2
    public function itemCssClass(string $value): self
324
    {
325 2
        $new = clone $this;
326 2
        $new->itemCssClass = $value;
327 2
        return $new;
328
    }
329
330
    /**
331
     * Returns a new instance with the specified the role of the navbar.
332
     *
333
     * @param string $value
334
     *
335
     * @return self
336
     */
337 2
    public function role(string $value): self
338
    {
339 2
        $new = clone $this;
340 2
        $new->role = $value;
341 2
        return $new;
342
    }
343
344 18
    public function render(): string
345
    {
346 18
        return Html::closeTag('nav');
347
    }
348
349 18
    private function renderNavBar(): string
350
    {
351 18
        $attributes = $this->attributes;
352 18
        Html::addCssClass($attributes, $this->cssClass);
353
354 18
        if (!isset($attributes['id'])) {
355 17
            $attributes['id'] = Html::generateId($this->autoIdPrefix) . '-navbar';
356
        }
357
358 18
        $attributes['aria-label'] = $this->ariaLabel;
359 18
        $attributes['role'] = $this->role;
360
361 18
        return Html::openTag('nav', $attributes) . PHP_EOL . $this->renderNavBarBrand() . PHP_EOL;
362
    }
363
364 18
    private function renderNavBarBrand(): string
365
    {
366 18
        $brand = '';
367 18
        $brandImage = '';
368
369 18
        if ($this->brandImage !== '') {
370 2
            $brandImage = Img::tag()
371 2
                ->attributes($this->brandImageAttributes)
372 2
                ->url($this->brandImage)
373 2
                ->render();
374 2
            $brand = PHP_EOL . A::tag()
375 2
                ->class($this->itemCssClass)
376 2
                ->content($brandImage)
377 2
                ->encode(false)
378 2
                ->url($this->brandUrl)
379 2
                ->render();
380
        }
381
382 18
        if ($this->brandText !== '') {
383 4
            $brandText = $this->brandText;
384
385 4
            if ($brandImage !== '') {
386 1
                $brandText = $brandImage . $this->brandText;
387
            }
388
389 4
            if (empty($this->brandUrl)) {
390 1
                $brand = PHP_EOL . Span::tag()
391 1
                    ->addAttributes($this->brandTextAttributes)
392 1
                    ->addClass($this->itemCssClass)
393 1
                    ->content($brandText)
394 1
                    ->render();
395
            } else {
396 3
                $brand = PHP_EOL . A::tag()
397 3
                    ->addClass($this->itemCssClass)
398 3
                    ->content($brandText)
399 3
                    ->encode(false)
400 3
                    ->url($this->brandUrl)
401 3
                    ->render();
402
            }
403
        }
404
405 18
        $brand .= $this->renderNavBarBurger();
406
407 18
        return Div::tag()
408 18
            ->addAttributes($this->brandAttributes)
409 18
            ->addClass($this->brandCssClass)
410 18
            ->content($brand)
411 18
            ->encode(false)
412 18
            ->render();
413
    }
414
415
    /**
416
     * Renders collapsible toggle button.
417
     *
418
     * @return string the rendering navbar burger link button.
419
     *
420
     * @link https://bulma.io/documentation/components/navbar/#navbar-burger
421
     */
422 18
    private function renderNavBarBurger(): string
423
    {
424 18
        $burgerAttributes = $this->burgerAttributes;
425 18
        if ($this->buttonLinkContent === '') {
426 17
            $this->buttonLinkContent = PHP_EOL .
427 17
                Span::tag()
428 17
                    ->attributes(['aria-hidden' => 'true'])
429 17
                    ->render() . PHP_EOL .
430 17
                Span::tag()
431 17
                    ->attributes(['aria-hidden' => 'true'])
432 17
                    ->render() . PHP_EOL .
433 17
                Span::tag()
434 17
                    ->attributes(['aria-hidden' => 'true'])
435 17
                    ->render() . PHP_EOL;
436
        }
437
438 18
        $burgerAttributes['aria-expanded'] = $this->buttonLinkAriaExpanded;
439 18
        $burgerAttributes['aria-label'] = $this->buttonLinkAriaLabelText;
440 18
        $burgerAttributes['role'] = $this->buttonLinkRole;
441
442 18
        return PHP_EOL . A::tag()
443 18
            ->addAttributes($burgerAttributes)
444 18
            ->addClass($this->burgerCssClass)
445 18
            ->content($this->buttonLinkContent)
446 18
            ->encode(false)
447 18
            ->render() . PHP_EOL;
448
    }
449
}
450