Passed
Push — master ( 8617c9...9932bf )
by Alexander
03:51 queued 01:34
created

Modal::renderToggleButton()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Bulma;
6
7
use InvalidArgumentException;
8
use Yiisoft\Html\Html;
9
10
/**
11
 * Modal renders a modal window that can be toggled by clicking on a button.
12
 *
13
 * The following example will show the content enclosed between the {@see begin()} and {@see end()} calls within the
14
 * modal window:
15
 *
16
 * ```php
17
 * echo Modal::widget()->begin();
18
 *
19
 * echo 'Say hello...';
20
 *
21
 * echo Modal::end();
22
 * ```
23
 *
24
 * @link https://bulma.io/documentation/components/modal/
25
 */
26
final class Modal extends Widget
27
{
28
    public const SIZE_SMALL = 'is-small';
29
    public const SIZE_MEDIUM = 'is-medium';
30
    public const SIZE_LARGE = 'is-large';
31
    private const SIZE_ALL = [
32
        self::SIZE_SMALL,
33
        self::SIZE_MEDIUM,
34
        self::SIZE_LARGE,
35
    ];
36
37
    public const COLOR_PRIMARY = 'is-primary';
38
    public const COLOR_LINK = 'is-link';
39
    public const COLOR_INFO = 'is-info';
40
    public const COLOR_SUCCESS = 'is-success';
41
    public const COLOR_WARNING = 'is-warning';
42
    public const COLOR_DANGER = 'is-danger';
43
    private const COLOR_ALL = [
44
        self::COLOR_PRIMARY,
45
        self::COLOR_LINK,
46
        self::COLOR_INFO,
47
        self::COLOR_SUCCESS,
48
        self::COLOR_WARNING,
49
        self::COLOR_DANGER,
50
    ];
51
52
    private array $options = [];
53
    private array $contentOptions = [];
54
    private array $closeButtonOptions = [];
55
    private string $closeButtonSize = '';
56
    private bool $closeButtonEnabled = true;
57
    private string $toggleButtonLabel = 'Toggle button';
58
    private string $toggleButtonSize = '';
59
    private string $toggleButtonColor = '';
60
    private array $toggleButtonOptions = [];
61
    private bool $toggleButtonEnabled = true;
62
63 10
    public function begin(): ?string
64
    {
65 10
        parent::begin();
66
67 10
        $this->buildOptions();
68
69 10
        $html = '';
70 10
        $html .= $this->renderToggleButton() . "\n";
71 10
        $html .= Html::beginTag('div', $this->options) . "\n"; // .modal
72 10
        $html .= Html::tag('div', '', ['class' => 'modal-background']) . "\n";
73 10
        $html .= $this->renderCloseButton() . "\n";
74 10
        $html .= Html::beginTag('div', $this->contentOptions) . "\n"; // .modal-content
75
76 10
        return $html;
77
    }
78
79 10
    protected function run(): string
80
    {
81 10
        $html = '';
82 10
        $html .= Html::endTag('div') . "\n"; // .modal-content
83 10
        $html .= Html::endTag('div'); // .modal
84
85 10
        return $html;
86
    }
87
88 10
    private function buildOptions(): void
89
    {
90 10
        $this->options['id'] ??= "{$this->getId()}-modal";
91 10
        $this->options = $this->addOptions($this->options, 'modal');
92
93 10
        $this->contentOptions = $this->addOptions($this->contentOptions, 'modal-content');
94
95 10
        $this->closeButtonOptions = $this->addOptions($this->closeButtonOptions, 'modal-close');
96 10
        $this->closeButtonOptions['aria-label'] = 'close';
97
98 10
        if ($this->closeButtonSize !== '') {
99 1
            Html::addCssClass($this->closeButtonOptions, $this->closeButtonSize);
100
        }
101
102 10
        $this->toggleButtonOptions = $this->addOptions($this->toggleButtonOptions, 'button');
103 10
        $this->toggleButtonOptions['data-target'] = '#' . $this->options['id'];
104 10
        $this->toggleButtonOptions['aria-haspopup'] = 'true';
105
106 10
        if ($this->toggleButtonSize !== '') {
107 1
            Html::addCssClass($this->toggleButtonOptions, $this->toggleButtonSize);
108
        }
109
110 10
        if ($this->toggleButtonColor !== '') {
111 1
            Html::addCssClass($this->toggleButtonOptions, $this->toggleButtonColor);
112
        }
113 10
    }
114
115
    /**
116
     * Main container options.
117
     *
118
     * {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
119
     *
120
     * @param array $value
121
     *
122
     * @return self
123
     */
124 1
    public function options(array $value): self
125
    {
126 1
        $new = clone $this;
127 1
        $new->options = $value;
128
129 1
        return $new;
130
    }
131
132
    /**
133
     * Toggle button label.
134
     *
135
     * @param string $value
136
     *
137
     * @return self
138
     */
139 1
    public function toggleButtonLabel(string $value): self
140
    {
141 1
        $new = clone $this;
142 1
        $new->toggleButtonLabel = $value;
143
144 1
        return $new;
145
    }
146
147
    /**
148
     * Toggle button options.
149
     *
150
     * {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
151
     *
152
     * @param array $value
153
     *
154
     * @return self
155
     */
156
    public function toggleButtonOptions(array $value): self
157
    {
158
        $new = clone $this;
159
        $new->toggleButtonOptions = $value;
160
161
        return $new;
162
    }
163
164
    /**
165
     * Toggle button size.
166
     *
167
     * @param string $value
168
     *
169
     * @return self
170
     */
171 2
    public function toggleButtonSize(string $value): self
172
    {
173 2
        if (!in_array($value, self::SIZE_ALL)) {
174 1
            $values = implode('", "', self::SIZE_ALL);
175 1
            throw new InvalidArgumentException("Invalid size. Valid values are: \"$values\".");
176
        }
177
178 1
        $new = clone $this;
179 1
        $new->toggleButtonSize = $value;
180
181 1
        return $new;
182
    }
183
184
    /**
185
     * Toggle button color.
186
     *
187
     * @param string $value
188
     *
189
     * @return self
190
     */
191 1
    public function toggleButtonColor(string $value): self
192
    {
193 1
        if (!in_array($value, self::COLOR_ALL)) {
194
            $values = implode('", "', self::COLOR_ALL);
195
            throw new InvalidArgumentException("Invalid color. Valid values are: \"$values\".");
196
        }
197
198 1
        $new = clone $this;
199 1
        $new->toggleButtonColor = $value;
200
201 1
        return $new;
202
    }
203
204
    /**
205
     * Enable/Disable toggle button.
206
     *
207
     * @param bool $value
208
     *
209
     * @return self
210
     */
211 3
    public function toggleButtonEnabled(bool $value): self
212
    {
213 3
        $new = clone $this;
214 3
        $new->toggleButtonEnabled = $value;
215
216 3
        return $new;
217
    }
218
219
    /**
220
     * Renders the toggle button.
221
     *
222
     * @return string
223
     * @throws \JsonException
224
     */
225 10
    private function renderToggleButton(): string
226
    {
227 10
        if ($this->toggleButtonEnabled) {
228 7
            return Html::button($this->toggleButtonLabel, $this->toggleButtonOptions);
229
        }
230
231 3
        return '';
232
    }
233
234
    /**
235
     * Close button size.
236
     *
237
     * @param string $value
238
     *
239
     * @return self
240
     */
241 1
    public function closeButtonSize(string $value): self
242
    {
243 1
        if (!in_array($value, self::SIZE_ALL)) {
244
            $values = implode('"', self::SIZE_ALL);
245
            throw new InvalidArgumentException("Invalid size. Valid values are: \"$values\".");
246
        }
247
248 1
        $new = clone $this;
249 1
        $new->closeButtonSize = $value;
250
251 1
        return $new;
252
    }
253
254
    /**
255
     * Close button options
256
     *
257
     * {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
258
     *
259
     * @param array $value
260
     *
261
     * @return self
262
     */
263 1
    public function closeButtonOptions(array $value): self
264
    {
265 1
        $new = clone $this;
266 1
        $new->closeButtonOptions = $value;
267
268 1
        return $new;
269
    }
270
271
    /**
272
     * Enable/Disable close button.
273
     *
274
     * @param bool $value
275
     *
276
     * @return self
277
     */
278 3
    public function closeButtonEnabled(bool $value): self
279
    {
280 3
        $new = clone $this;
281 3
        $new->closeButtonEnabled = $value;
282
283 3
        return $new;
284
    }
285
286
    /**
287
     * Renders the close button.
288
     *
289
     * @return string
290
     * @throws \JsonException
291
     */
292 10
    private function renderCloseButton(): string
293
    {
294 10
        if ($this->closeButtonEnabled) {
295 7
            return Html::button('', $this->closeButtonOptions);
296
        }
297
298 3
        return '';
299
    }
300
301
    /**
302
     * Content options.
303
     *
304
     * {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
305
     *
306
     * @param array $value
307
     *
308
     * @return self
309
     */
310 1
    public function contentOptions(array $value): self
311
    {
312 1
        $new = clone $this;
313 1
        $new->contentOptions = $value;
314
315 1
        return $new;
316
    }
317
}
318