Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 49 |
|
0.00% |
0 / 15 |
CRAP | |
0.00% |
0 / 1 |
TextInputBuilder | |
0.00% |
0 / 49 |
|
0.00% |
0 / 15 |
380 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setType | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
setName | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setValue | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setInputId | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setHasStartIcon | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setHasEndIcon | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setDisabled | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setStatus | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
setStartIconClass | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setEndIconClass | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setInputAttributes | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
setWrapperAttributes | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
setPlaceholder | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
build | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * TextInputBuilder |
4 | * |
5 | * This file is part of the Codex design system, the official design system |
6 | * for Wikimedia projects. It provides the `TextInput` class, a builder for constructing |
7 | * text input components using the Codex design system. |
8 | * |
9 | * A text input is a form element that lets users input and edit a single-line text value. |
10 | * |
11 | * @category Builder |
12 | * @package Codex\Builder |
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 | |
19 | namespace Wikimedia\Codex\Builder; |
20 | |
21 | use InvalidArgumentException; |
22 | use Wikimedia\Codex\Component\TextInput; |
23 | use Wikimedia\Codex\Renderer\TextInputRenderer; |
24 | |
25 | /** |
26 | * TextInputBuilder |
27 | * |
28 | * This class implements the builder pattern to construct instances of TextInput. |
29 | * It provides a fluent interface for setting various properties and building the |
30 | * final immutable object with predefined configurations and immutability. |
31 | * |
32 | * @category Builder |
33 | * @package Codex\Builder |
34 | * @since 0.1.0 |
35 | * @author Doğu Abaris <abaris@null.net> |
36 | * @license https://www.gnu.org/copyleft/gpl.html GPL-2.0-or-later |
37 | * @link https://doc.wikimedia.org/codex/main/ Codex Documentation |
38 | */ |
39 | class TextInputBuilder { |
40 | |
41 | /** |
42 | * Supported input types for the text input. |
43 | */ |
44 | private const TEXT_INPUT_TYPES = [ |
45 | 'text', |
46 | 'search', |
47 | 'number', |
48 | 'email', |
49 | 'month', |
50 | 'password', |
51 | 'tel', |
52 | 'url', |
53 | 'week', |
54 | 'date', |
55 | 'datetime-local', |
56 | 'time', |
57 | ]; |
58 | |
59 | /** |
60 | * Allowed validation statuses for the TextInput. |
61 | */ |
62 | private const ALLOWED_STATUSES = [ |
63 | 'default', |
64 | 'error', |
65 | 'warning', |
66 | 'success' |
67 | ]; |
68 | |
69 | /** |
70 | * Input field type. |
71 | */ |
72 | private string $type = 'text'; |
73 | |
74 | /** |
75 | * Whether to show a start icon. |
76 | */ |
77 | private bool $hasStartIcon = false; |
78 | |
79 | /** |
80 | * Whether to show an end icon. |
81 | */ |
82 | private bool $hasEndIcon = false; |
83 | |
84 | /** |
85 | * Whether the input is disabled. |
86 | */ |
87 | private bool $disabled = false; |
88 | |
89 | /** |
90 | * Validation status for the input. |
91 | */ |
92 | private string $status = 'default'; |
93 | |
94 | /** |
95 | * CSS class for the start icon. |
96 | */ |
97 | private string $startIconClass = ''; |
98 | |
99 | /** |
100 | * CSS class for the end icon. |
101 | */ |
102 | private string $endIconClass = ''; |
103 | |
104 | /** |
105 | * Additional HTML attributes for the TextInput. |
106 | */ |
107 | private array $inputAttributes = []; |
108 | |
109 | /** |
110 | * Additional attributes for the wrapper element. |
111 | */ |
112 | private array $wrapperAttributes = []; |
113 | |
114 | /** |
115 | * Placeholder text for the TextInput. |
116 | */ |
117 | private string $placeholder = ''; |
118 | |
119 | /** |
120 | * The name attribute of the TextInput. |
121 | */ |
122 | private string $name = ''; |
123 | |
124 | /** |
125 | * The default value of the TextInput. |
126 | */ |
127 | private string $value = ''; |
128 | |
129 | /** |
130 | * ID attribute for the TextInput. |
131 | */ |
132 | private string $inputId = ''; |
133 | |
134 | /** |
135 | * The renderer instance used to render the text input. |
136 | */ |
137 | protected TextInputRenderer $renderer; |
138 | |
139 | /** |
140 | * Constructor for the TextInputBuilder class. |
141 | * |
142 | * @param TextInputRenderer $renderer The renderer to use for rendering the text input. |
143 | */ |
144 | public function __construct( TextInputRenderer $renderer ) { |
145 | $this->renderer = $renderer; |
146 | } |
147 | |
148 | /** |
149 | * Set the type of the input field. |
150 | * |
151 | * This method sets the type attribute of the input field, which determines |
152 | * the type of data the input field accepts, such as 'text', 'email', 'password', etc. |
153 | * |
154 | * Example usage: |
155 | * |
156 | * $textInput->setType('email'); |
157 | * |
158 | * @since 0.1.0 |
159 | * @param string $type The type of the input field (e.g., 'text', 'email'). |
160 | * @return $this Returns the TextInput instance for method chaining. |
161 | */ |
162 | public function setType( string $type ): self { |
163 | if ( !in_array( $type, self::TEXT_INPUT_TYPES, true ) ) { |
164 | throw new InvalidArgumentException( "Invalid input type: $type" ); |
165 | } |
166 | $this->type = $type; |
167 | |
168 | return $this; |
169 | } |
170 | |
171 | /** |
172 | * Set the name attribute for the input field. |
173 | * |
174 | * This method specifies the name attribute for the input field, which is used to identify |
175 | * the input form control when submitting the form data. |
176 | * |
177 | * Example usage: |
178 | * |
179 | * $textInput->setName('email'); |
180 | * |
181 | * @since 0.1.0 |
182 | * @param string $name The name attribute for the input field. |
183 | * @return $this Returns the TextInput instance for method chaining. |
184 | */ |
185 | public function setName( string $name ): self { |
186 | $this->name = $name; |
187 | |
188 | return $this; |
189 | } |
190 | |
191 | /** |
192 | * Set the value attribute for the input field. |
193 | * |
194 | * This method specifies the value attribute for the input field, which represents the |
195 | * current value of the input field. |
196 | * |
197 | * Example usage: |
198 | * |
199 | * $textInput->setValue('example@example.com'); |
200 | * |
201 | * @since 0.1.0 |
202 | * @param string $value The value of the input field. |
203 | * @return $this Returns the TextInput instance for method chaining. |
204 | */ |
205 | public function setValue( string $value ): self { |
206 | $this->value = $value; |
207 | |
208 | return $this; |
209 | } |
210 | |
211 | /** |
212 | * Set the ID for the input field. |
213 | * |
214 | * This method sets the ID attribute for the input field, which is useful for linking |
215 | * the input field to a label or for other JavaScript interactions. |
216 | * |
217 | * Example usage: |
218 | * |
219 | * $textInput->setInputId('email-input'); |
220 | * |
221 | * @since 0.1.0 |
222 | * @param string $inputId The ID of the input field. |
223 | * @return $this Returns the TextInput instance for method chaining. |
224 | */ |
225 | public function setInputId( string $inputId ): self { |
226 | $this->inputId = $inputId; |
227 | |
228 | return $this; |
229 | } |
230 | |
231 | /** |
232 | * Set whether the input has a start icon. |
233 | * |
234 | * This method specifies whether the input field should have an icon at the start. |
235 | * The icon can be used to visually indicate the type of input expected. |
236 | * |
237 | * Example usage: |
238 | * |
239 | * $textInput->setHasStartIcon(true); |
240 | * |
241 | * @since 0.1.0 |
242 | * @param bool $hasStartIcon Indicates whether the input field has a start icon. |
243 | * @return $this Returns the TextInput instance for method chaining. |
244 | */ |
245 | public function setHasStartIcon( bool $hasStartIcon ): self { |
246 | $this->hasStartIcon = $hasStartIcon; |
247 | |
248 | return $this; |
249 | } |
250 | |
251 | /** |
252 | * Set whether the input has an end icon. |
253 | * |
254 | * This method specifies whether the input field should have an icon at the end. |
255 | * The icon can be used to visually indicate additional functionality or context. |
256 | * |
257 | * Example usage: |
258 | * |
259 | * $textInput->setHasEndIcon(true); |
260 | * |
261 | * @since 0.1.0 |
262 | * @param bool $hasEndIcon Indicates whether the input field has an end icon. |
263 | * @return $this Returns the TextInput instance for method chaining. |
264 | */ |
265 | public function setHasEndIcon( bool $hasEndIcon ): self { |
266 | $this->hasEndIcon = $hasEndIcon; |
267 | |
268 | return $this; |
269 | } |
270 | |
271 | /** |
272 | * Set whether the input is disabled. |
273 | * |
274 | * This method disables the input field, making it uneditable and visually distinct. |
275 | * The disabled attribute is useful for read-only forms or when the input is temporarily inactive. |
276 | * |
277 | * Example usage: |
278 | * |
279 | * $textInput->setDisabled(true); |
280 | * |
281 | * @since 0.1.0 |
282 | * @param bool $disabled Indicates whether the input field should be disabled. |
283 | * @return $this Returns the TextInput instance for method chaining. |
284 | */ |
285 | public function setDisabled( bool $disabled ): self { |
286 | $this->disabled = $disabled; |
287 | |
288 | return $this; |
289 | } |
290 | |
291 | /** |
292 | * Set the validation status for the input. |
293 | * |
294 | * Example usage: |
295 | * |
296 | * $textInput->setStatus('error'); |
297 | * |
298 | * @since 0.1.0 |
299 | * @param string $status Current validation status. |
300 | * @return $this |
301 | */ |
302 | public function setStatus( string $status ): self { |
303 | if ( !in_array( $status, self::ALLOWED_STATUSES, true ) ) { |
304 | throw new InvalidArgumentException( "Invalid status: $status" ); |
305 | } |
306 | $this->status = $status; |
307 | |
308 | return $this; |
309 | } |
310 | |
311 | /** |
312 | * Set the CSS class for the start icon. |
313 | * |
314 | * This method specifies the CSS class that will be applied to the start icon. |
315 | * The class can be used to style the icon or apply a background image. |
316 | * |
317 | * Example usage: |
318 | * |
319 | * $textInput->setStartIconClass('icon-class-name'); |
320 | * |
321 | * @since 0.1.0 |
322 | * @param string $startIconClass The CSS class for the start icon. |
323 | * @return $this Returns the TextInput instance for method chaining. |
324 | */ |
325 | public function setStartIconClass( string $startIconClass ): self { |
326 | $this->startIconClass = $startIconClass; |
327 | |
328 | return $this; |
329 | } |
330 | |
331 | /** |
332 | * Set the CSS class for the end icon. |
333 | * |
334 | * This method specifies the CSS class that will be applied to the end icon. |
335 | * The class can be used to style the icon or apply a background image. |
336 | * |
337 | * Example usage: |
338 | * |
339 | * $textInput->setEndIconClass('icon-class-name'); |
340 | * |
341 | * @since 0.1.0 |
342 | * @param string $endIconClass The CSS class for the end icon. |
343 | * @return $this Returns the TextInput instance for method chaining. |
344 | */ |
345 | public function setEndIconClass( string $endIconClass ): self { |
346 | $this->endIconClass = $endIconClass; |
347 | |
348 | return $this; |
349 | } |
350 | |
351 | /** |
352 | * Set additional HTML attributes for the input element. |
353 | * |
354 | * This method allows custom HTML attributes to be added to the input element, such as `data-*`, |
355 | * `aria-*`, or any other valid attributes that enhance functionality or accessibility. |
356 | * |
357 | * Example usage: |
358 | * |
359 | * $textInput->setInputAttributes(['data-test' => 'value']); |
360 | * |
361 | * @since 0.1.0 |
362 | * @param array $inputAttributes An associative array of HTML attributes for the input element. |
363 | * @return $this Returns the TextInput instance for method chaining. |
364 | */ |
365 | public function setInputAttributes( array $inputAttributes ): self { |
366 | foreach ( $inputAttributes as $key => $value ) { |
367 | $this->inputAttributes[$key] = $value; |
368 | } |
369 | return $this; |
370 | } |
371 | |
372 | /** |
373 | * Set additional HTML attributes for the outer wrapper element. |
374 | * |
375 | * This method allows custom HTML attributes to be added to the outer wrapper element, |
376 | * enhancing its behavior or styling. |
377 | * |
378 | * Example usage: |
379 | * |
380 | * $textInput->setWrapperAttributes(['id' => 'custom-wrapper']); |
381 | * |
382 | * @since 0.1.0 |
383 | * @param array $wrapperAttributes An associative array of HTML attributes for the wrapper element. |
384 | * @return $this Returns the TextInput instance for method chaining. |
385 | */ |
386 | public function setWrapperAttributes( array $wrapperAttributes ): self { |
387 | foreach ( $wrapperAttributes as $key => $value ) { |
388 | $this->wrapperAttributes[$key] = $value; |
389 | } |
390 | return $this; |
391 | } |
392 | |
393 | /** |
394 | * Set the placeholder text for the input element. |
395 | * |
396 | * This method sets the placeholder text, which is displayed when the input field is empty. |
397 | * It provides a hint to the user about what should be entered in the field. |
398 | * |
399 | * Example usage: |
400 | * |
401 | * $textInput->setPlaceholder('johndoe@example.com'); |
402 | * |
403 | * @since 0.1.0 |
404 | * @param string $placeholder The placeholder text for the input field. |
405 | * @return $this Returns the TextInput instance for method chaining. |
406 | */ |
407 | public function setPlaceholder( string $placeholder ): self { |
408 | $this->placeholder = $placeholder; |
409 | |
410 | return $this; |
411 | } |
412 | |
413 | /** |
414 | * Build and return the TextInput component object. |
415 | * This method constructs the immutable TextInput object with all the properties set via the builder. |
416 | * |
417 | * @since 0.1.0 |
418 | * @return TextInput The constructed TextInput. |
419 | */ |
420 | public function build(): TextInput { |
421 | return new TextInput( |
422 | $this->type, |
423 | $this->hasStartIcon, |
424 | $this->hasEndIcon, |
425 | $this->disabled, |
426 | $this->status, |
427 | $this->startIconClass, |
428 | $this->endIconClass, |
429 | $this->inputAttributes, |
430 | $this->wrapperAttributes, |
431 | $this->placeholder, |
432 | $this->name, |
433 | $this->value, |
434 | $this->inputId, |
435 | $this->renderer |
436 | ); |
437 | } |
438 | } |