Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 29
CRAP
0.00% covered (danger)
0.00%
0 / 1
TextArea
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 29
1056
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getInputId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getValue
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getInputAttributes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getWrapperAttributes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isDisabled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isReadonly
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 hasStartIcon
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 hasEndIcon
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getStartIconClass
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEndIconClass
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPlaceholder
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getStatus
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setInputId
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setName
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setValue
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setinputAttributes
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 setTextAreaAttributes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setWrapperAttributes
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 setDisabled
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setReadonly
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setHasStartIcon
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setHasEndIcon
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setStartIconClass
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setEndIconClass
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setPlaceholder
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setStatus
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2declare( strict_types = 1 );
3
4/**
5 * TextArea.php
6 *
7 * This file is part of the Codex design system, the official design system for Wikimedia projects.
8 * It contains the definition and implementation of the `TextArea` class, responsible for managing
9 * the behavior and properties of the corresponding component.
10 *
11 * @category Component
12 * @package  Codex\Component
13 * @since    0.1.0
14 * @author   Doğu Abaris <abaris@null.net>
15 * @license  https://www.gnu.org/copyleft/gpl.html GPL-2.0-or-later
16 * @link     https://doc.wikimedia.org/codex/main/ Codex Documentation
17 */
18
19namespace Wikimedia\Codex\Component;
20
21use InvalidArgumentException;
22use Wikimedia\Codex\Contract\Component;
23use Wikimedia\Codex\Renderer\TextAreaRenderer;
24
25/**
26 * TextArea
27 *
28 * @category Component
29 * @package  Codex\Component
30 * @since    0.1.0
31 * @author   Doğu Abaris <abaris@null.net>
32 * @license  https://www.gnu.org/copyleft/gpl.html GPL-2.0-or-later
33 * @link     https://doc.wikimedia.org/codex/main/ Codex Documentation
34 */
35class TextArea extends Component {
36    /**
37     * Allowed values for the status type.
38     */
39    public const ALLOWED_STATUS_TYPES = [
40        'notice',
41        'warning',
42        'error',
43        'success',
44    ];
45
46    public function __construct(
47        TextAreaRenderer $renderer,
48        private string $name,
49        private string $value,
50        private string $inputId,
51        private array $inputAttributes,
52        private array $wrapperAttributes,
53        private bool $disabled,
54        private bool $readonly,
55        private bool $hasStartIcon,
56        private bool $hasEndIcon,
57        private string $startIconClass,
58        private string $endIconClass,
59        private string $placeholder,
60        private string $status
61    ) {
62        parent::__construct( $renderer );
63    }
64
65    /**
66     * Get the HTML ID for the textarea.
67     *
68     * This method returns the HTML `id` attribute value for the textarea element.
69     *
70     * @since 0.1.0
71     * @return string The ID for the textarea.
72     */
73    public function getInputId(): string {
74        return $this->inputId;
75    }
76
77    /**
78     * Get the name attribute of the textarea element.
79     *
80     * This method returns the name attribute of the textarea, which is used to identify
81     * the textarea form control when submitting the form data.
82     *
83     * @since 0.1.0
84     * @return string The name attribute of the textarea.
85     */
86    public function getName(): string {
87        return $this->name;
88    }
89
90    /**
91     * Get the value of the textarea element.
92     *
93     * This method returns the current content inside the textarea, which could be
94     * the default value or any content that was previously set.
95     *
96     * @since 0.1.0
97     * @return string The value of the textarea.
98     */
99    public function getValue(): string {
100        return $this->value;
101    }
102
103    /**
104     * Get the additional HTML attributes for the textarea element.
105     *
106     * This method returns an associative array of custom HTML attributes applied to the textarea.
107     * These attributes can be used to enhance accessibility or integrate with JavaScript.
108     *
109     * @since 0.1.0
110     * @return array The additional attributes as an array.
111     */
112    public function getInputAttributes(): array {
113        return $this->inputAttributes;
114    }
115
116    /**
117     * Get additional HTML attributes for the outer wrapper element.
118     *
119     * This method returns an associative array of custom HTML attributes that are applied to the outer wrapper element,
120     * enhancing its behavior or styling.
121     *
122     * @since 0.1.0
123     * @return array The additional attributes as an array.
124     */
125    public function getWrapperAttributes(): array {
126        return $this->wrapperAttributes;
127    }
128
129    /**
130     * Check if the textarea is disabled.
131     *
132     * This method returns a boolean indicating whether the textarea is disabled.
133     * A disabled textarea is not editable and has a distinct visual appearance.
134     *
135     * @since 0.1.0
136     * @return bool True if the textarea is disabled, false otherwise.
137     */
138    public function isDisabled(): bool {
139        return $this->disabled;
140    }
141
142    /**
143     * Check if the textarea is read-only.
144     *
145     * This method returns a boolean indicating whether the textarea is read-only.
146     * A read-only textarea cannot be modified by the user but can be selected and copied.
147     *
148     * @since 0.1.0
149     * @return bool True if the textarea is read-only, false otherwise.
150     */
151    public function isReadonly(): bool {
152        return $this->readonly;
153    }
154
155    /**
156     * Check if the textarea has a start icon.
157     *
158     * This method returns a boolean indicating whether the textarea includes an icon at the start.
159     * The start icon is typically used to visually indicate the type of input expected.
160     *
161     * @since 0.1.0
162     * @return bool True if the textarea has a start icon, false otherwise.
163     */
164    public function hasStartIcon(): bool {
165        return $this->hasStartIcon;
166    }
167
168    /**
169     * Check if the textarea has an end icon.
170     *
171     * This method returns a boolean indicating whether the textarea includes an icon at the end.
172     * The end icon is typically used to visually indicate additional functionality or context.
173     *
174     * @since 0.1.0
175     * @return bool True if the textarea has an end icon, false otherwise.
176     */
177    public function hasEndIcon(): bool {
178        return $this->hasEndIcon;
179    }
180
181    /**
182     * Get the CSS class for the start icon.
183     *
184     * This method returns the CSS class applied to the start icon. This class can be used
185     * to style the icon or apply a background image.
186     *
187     * @since 0.1.0
188     * @return string The CSS class for the start icon.
189     */
190    public function getStartIconClass(): string {
191        return $this->startIconClass;
192    }
193
194    /**
195     * Get the CSS class for the end icon.
196     *
197     * This method returns the CSS class applied to the end icon. This class can be used
198     * to style the icon or apply a background image.
199     *
200     * @since 0.1.0
201     * @return string The CSS class for the end icon.
202     */
203    public function getEndIconClass(): string {
204        return $this->endIconClass;
205    }
206
207    /**
208     * Get the placeholder text of the textarea element.
209     *
210     * This method returns the placeholder text displayed inside the textarea when it is empty.
211     * The placeholder provides a hint to the user about the expected input.
212     *
213     * @since 0.1.0
214     * @return string The placeholder text of the textarea.
215     */
216    public function getPlaceholder(): string {
217        return $this->placeholder;
218    }
219
220    /**
221     * Get the validation status of the textarea.
222     *
223     * This method returns a string value indicating the current validation status, which is used to
224     * add a CSS class that can be used for special styles per status.
225     *
226     * @since 0.1.0
227     * @return string Validation status, e.g. 'default' or 'error'.
228     */
229    public function getStatus(): string {
230        return $this->status;
231    }
232
233    /**
234     * Set the TextArea HTML ID attribute.
235     *
236     * @since 0.1.0
237     * @param string $inputId The ID for the TextArea element.
238     * @return $this
239     */
240    public function setInputId( string $inputId ): self {
241        $this->inputId = $inputId;
242
243        return $this;
244    }
245
246    /**
247     * @deprecated Use setInputId() instead
248     */
249    public function setId( string $id ): self {
250        return $this->setInputId( $id );
251    }
252
253    /**
254     * Set the name attribute for the textarea element.
255     *
256     * This method sets the name attribute for the textarea element, which is used to identify
257     * the textarea form control when submitting the form data.
258     *
259     * Example usage:
260     *
261     *     $textArea->setName('description');
262     *
263     * @since 0.1.0
264     * @param string $name The name attribute for the textarea.
265     * @return $this Returns the TextArea instance for method chaining.
266     */
267    public function setName( string $name ): self {
268        $this->name = $name;
269
270        return $this;
271    }
272
273    /**
274     * Set the default content inside the textarea.
275     *
276     * This method sets the initial content that will be displayed inside the textarea.
277     * The content can be prefilled with a default value if necessary.
278     *
279     * Example usage:
280     *
281     *     $textArea->setValue('Default content...');
282     *
283     * @since 0.1.0
284     * @param mixed $value The content to be displayed inside the textarea.
285     * @return $this Returns the TextArea instance for method chaining.
286     */
287    public function setValue( $value ): self {
288        $this->value = $value;
289
290        return $this;
291    }
292
293    /**
294     * Set additional HTML attributes for the textarea element.
295     *
296     * This method allows custom HTML attributes to be added to the textarea element,
297     * such as `id`, `data-*`, `aria-*`, or any other valid attributes that enhance functionality or accessibility.
298     *
299     * Example usage:
300     *
301     *     $textArea->setinputAttributes([
302     *         'id' => 'text-area-id',
303     *         'data-category' => 'input',
304     *     ]);
305     *
306     * @since 0.1.0
307     * @param array $inputAttributes An associative array of HTML attributes for the textarea element.
308     * @return $this Returns the TextArea instance for method chaining.
309     */
310    public function setinputAttributes( array $inputAttributes ): self {
311        foreach ( $inputAttributes as $key => $value ) {
312            $this->inputAttributes[$key] = $value;
313        }
314
315        return $this;
316    }
317
318    /**
319     * @deprecated Use setInputAttributes() instead
320     */
321    public function setTextAreaAttributes( array $textAreaAttributes ): self {
322        return $this->setInputAttributes( $textAreaAttributes );
323    }
324
325    /**
326     * Set additional HTML attributes for the outer wrapper element.
327     *
328     * This method allows custom HTML attributes to be added to the outer wrapper element,
329     * enhancing its behavior or styling.
330     *
331     * Example usage:
332     *
333     *        $textArea->setWrapperAttributes(['id' => 'custom-wrapper']);
334     *
335     * @since 0.1.0
336     * @param array $wrapperAttributes An associative array of HTML attributes.
337     * @return $this Returns the TextArea instance for method chaining.
338     */
339    public function setWrapperAttributes( array $wrapperAttributes ): self {
340        foreach ( $wrapperAttributes as $key => $value ) {
341            $this->wrapperAttributes[$key] = $value;
342        }
343
344        return $this;
345    }
346
347    /**
348     * Set the disabled state for the textarea.
349     *
350     * This method disables the textarea, making it uneditable and visually distinct.
351     * The disabled attribute is useful for read-only forms or when the input is temporarily inactive.
352     *
353     * Example usage:
354     *
355     *     $textArea->setDisabled(true);
356     *
357     * @since 0.1.0
358     * @param bool $disabled Indicates whether the textarea should be disabled.
359     * @return $this Returns the TextArea instance for method chaining.
360     */
361    public function setDisabled( bool $disabled ): self {
362        $this->disabled = $disabled;
363
364        return $this;
365    }
366
367    /**
368     * Set the readonly state for the textarea.
369     *
370     * This method makes the textarea read-only, meaning users can view the content
371     * but cannot modify it. The readonly attribute is useful when displaying static content.
372     *
373     * Example usage:
374     *
375     *     $textArea->setReadonly(true);
376     *
377     * @since 0.1.0
378     * @param bool $readonly Indicates whether the textarea should be read-only.
379     * @return $this Returns the TextArea instance for method chaining.
380     */
381    public function setReadonly( bool $readonly ): self {
382        $this->readonly = $readonly;
383
384        return $this;
385    }
386
387    /**
388     * Set whether the textarea has a start icon.
389     *
390     * This method specifies whether the textarea should have an icon at the start.
391     * The icon can be used to visually indicate the type of input expected in the textarea.
392     *
393     * Example usage:
394     *
395     *     $textArea->setHasStartIcon(true);
396     *
397     * @since 0.1.0
398     * @param bool $hasStartIcon Indicates whether the textarea has a start icon.
399     * @return $this Returns the TextArea instance for method chaining.
400     */
401    public function setHasStartIcon( bool $hasStartIcon ): self {
402        $this->hasStartIcon = $hasStartIcon;
403
404        return $this;
405    }
406
407    /**
408     * Set whether the textarea has an end icon.
409     *
410     * This method specifies whether the textarea should have an icon at the end.
411     * The icon can be used to visually indicate additional functionality or context related to the input.
412     *
413     * Example usage:
414     *
415     *     $textArea->setHasEndIcon(true);
416     *
417     * @since 0.1.0
418     * @param bool $hasEndIcon Indicates whether the textarea has an end icon.
419     * @return $this Returns the TextArea instance for method chaining.
420     */
421    public function setHasEndIcon( bool $hasEndIcon ): self {
422        $this->hasEndIcon = $hasEndIcon;
423
424        return $this;
425    }
426
427    /**
428     * Set the CSS class for the start icon.
429     *
430     * This method specifies the CSS class that will be applied to the start icon.
431     * The class can be used to style the icon or apply a background image.
432     *
433     * Example usage:
434     *
435     *     $textArea->setStartIconClass('icon-class-name');
436     *
437     * @since 0.1.0
438     * @param string $startIconClass The CSS class for the start icon.
439     * @return $this Returns the TextArea instance for method chaining.
440     */
441    public function setStartIconClass( string $startIconClass ): self {
442        $this->startIconClass = $startIconClass;
443
444        return $this;
445    }
446
447    /**
448     * Set the CSS class for the end icon.
449     *
450     * This method specifies the CSS class that will be applied to the end icon.
451     * The class can be used to style the icon or apply a background image.
452     *
453     * Example usage:
454     *
455     *     $textArea->setEndIconClass('icon-class-name');
456     *
457     * @since 0.1.0
458     * @param string $endIconClass The CSS class for the end icon.
459     * @return $this Returns the TextArea instance for method chaining.
460     */
461    public function setEndIconClass( string $endIconClass ): self {
462        $this->endIconClass = $endIconClass;
463
464        return $this;
465    }
466
467    /**
468     * Set the placeholder text for the textarea element.
469     *
470     * This method specifies the placeholder text that will be displayed inside the textarea
471     * when it is empty. The placeholder provides a hint to the user about the expected input.
472     *
473     * Example usage:
474     *
475     *     $textArea->setPlaceholder('Rationale...');
476     *
477     * @since 0.1.0
478     * @param string $placeholder The placeholder text for the textarea.
479     * @return $this Returns the TextArea instance for method chaining.
480     */
481    public function setPlaceholder( string $placeholder ): self {
482        $this->placeholder = $placeholder;
483
484        return $this;
485    }
486
487    /**
488     * Set the validation status for the textarea.
489     *
490     * @since 0.1.0
491     * @param string $status Current validation status.
492     * @return $this
493     */
494    public function setStatus( string $status ): self {
495        if ( !in_array( $status, self::ALLOWED_STATUS_TYPES, true ) ) {
496            throw new InvalidArgumentException( "Invalid status: $status" );
497        }
498        $this->status = $status;
499
500        return $this;
501    }
502}