Passed
Push — master ( d5c6a7...b7d446 )
by Alexander
02:56
created

Modal::toggleButtonSize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

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