Passed
Push — master ( c202e1...34af4b )
by Alexander
20:59 queued 18:00
created

FieldAttributes::hint()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Widget\Attribute;
6
7
use Stringable;
8
9
abstract class FieldAttributes extends WidgetAttributes
10
{
11
    private ?bool $ariaDescribedBy = null;
12
    private ?bool $container = null;
13
    private array $containerAttributes = [];
14
    private string $containerClass = '';
15
    private array $defaultTokens = [];
16
    private array $defaultValues = [];
17
    private ?string $error = '';
18
    private array $errorAttributes = [];
19
    private string $errorClass = '';
20
    private array $errorMessageCallback = [];
21
    private string $errorTag = '';
22
    private ?string $hint = '';
23
    private array $hintAttributes = [];
24
    private string $hintClass = '';
25
    private string $hintTag = '';
26
    private string $inputClass = '';
27
    private ?string $label = '';
28
    private array $labelAttributes = [];
29
    private string $labelClass = '';
30
    private string $invalidClass = '';
31
    private string $validClass = '';
32
    private ?string $placeholder = null;
33
    private string $template = '';
34
    private string $type = '';
35
36
    /**
37
     * Set aria-describedby attribute.
38
     *
39
     * @param bool $value Whether to set aria-describedby attribute.
40
     *
41
     * @return static
42
     *
43
     * @link https://www.w3.org/TR/WCAG20-TECHS/ARIA1.html
44
     */
45 6
    public function ariaDescribedBy(bool $value): static
46
    {
47 6
        $new = clone $this;
48 6
        $new->ariaDescribedBy = $value;
49 6
        return $new;
50
    }
51
52
    /**
53
     * Set aria-label attribute.
54
     *
55
     * @param string $value
56
     *
57
     * @return static
58
     */
59 4
    public function ariaLabel(string $value): static
60
    {
61 4
        $new = clone $this;
62 4
        $new->attributes['aria-label'] = $value;
63 4
        return $new;
64
    }
65
66
    /**
67
     * Enable, disabled container for field.
68
     *
69
     * @param bool $value Is the container disabled or not.
70
     *
71
     * @return static
72
     */
73 8
    public function container(bool $value): static
74
    {
75 8
        $new = clone $this;
76 8
        $new->container = $value;
77 8
        return $new;
78
    }
79
80
    /**
81
     * Set container attributes.
82
     *
83
     * @param array $values Attribute values indexed by attribute names.
84
     *
85
     * ```php
86
     * ['class' => 'test-class']
87
     * ```
88
     *
89
     * @return static
90
     *
91
     * @psalm-param array<string, string> $values
92
     */
93 8
    public function containerAttributes(array $values): static
94
    {
95 8
        $new = clone $this;
96 8
        $new->containerAttributes = array_merge($new->containerAttributes, $values);
97 8
        return $new;
98
    }
99
100
    /**
101
     * Set container css class.
102
     *
103
     * @param string $value
104
     *
105
     * @return static
106
     */
107 13
    public function containerClass(string $value): static
108
    {
109 13
        $new = clone $this;
110 13
        $new->containerClass = $value;
111 13
        return $new;
112
    }
113
114
    /**
115
     * Set the ID of the container field.
116
     *
117
     * @param string|null $id
118
     *
119
     * @return static
120
     */
121 3
    public function containerId(?string $id): static
122
    {
123 3
        $new = clone $this;
124 3
        $new->containerAttributes['id'] = $id;
125 3
        return $new;
126
    }
127
128
    /**
129
     * Set the name of the container field.
130
     *
131
     * @param string|null $id
132
     *
133
     * @return static
134
     */
135 2
    public function containerName(?string $id): static
136
    {
137 2
        $new = clone $this;
138 2
        $new->containerAttributes['name'] = $id;
139 2
        return $new;
140
    }
141
142
    /**
143
     * Set default tokens.
144
     *
145
     * @param array $values Token values indexed by token names.
146
     *
147
     * @return static
148
     */
149 4
    public function defaultTokens(array $values): static
150
    {
151 4
        $new = clone $this;
152 4
        $new->defaultTokens = $values;
153 4
        return $new;
154
    }
155
156
    /**
157
     * Set default values for field widget.
158
     *
159
     * @param array $values The default values indexed by field type.
160
     *
161
     * ```php
162
     * [
163
     *     Text::class => [
164
     *         'label' => 'label-test',
165
     *     ],
166
     * ];
167
     *
168
     * @return static
169
     */
170 29
    public function defaultValues(array $values): static
171
    {
172 29
        $new = clone $this;
173 29
        $new->defaultValues = $values;
174 29
        return $new;
175
    }
176
177
    /**
178
     * Set error message for the field.
179
     *
180
     * @param string|null $value the error message.
181
     *
182
     * @return static The field widget instance.
183
     */
184 4
    public function error(?string $value): static
185
    {
186 4
        $new = clone $this;
187 4
        $new->error = $value;
188 4
        return $new;
189
    }
190
191
    /**
192
     * Set error attributes.
193
     *
194
     * @param array $values Attribute values indexed by attribute names.
195
     *
196
     * ```php
197
     * ['class' => 'test-class']
198
     * ```
199
     *
200
     * @return static The field widget instance.
201
     */
202 5
    public function errorAttributes(array $values): static
203
    {
204 5
        $new = clone $this;
205 5
        $new->errorAttributes = $values;
206 5
        return $new;
207
    }
208
209
    /**
210
     * Set error css class.
211
     *
212
     * @param string $value
213
     *
214
     * @return static
215
     */
216 10
    public function errorClass(string $value): static
217
    {
218 10
        $new = clone $this;
219 10
        $new->errorClass = $value;
220 10
        return $new;
221
    }
222
223
    /**
224
     * Callback that will be called to obtain an error message.
225
     *
226
     * The signature of the callback must be:
227
     *
228
     * ```php
229
     * [$FormModel, function()]
230
     * ```
231
     *
232
     * @param array $value
233
     *
234
     * @return static
235
     */
236 3
    public function errorMessageCallback(array $value): static
237
    {
238 3
        $new = clone $this;
239 3
        $new->errorMessageCallback = $value;
240 3
        return $new;
241
    }
242
243
    /**
244
     * The tag name of the container element.
245
     *
246
     * Empty to render error messages without container {@see Html::tag()}.
247
     *
248
     * @param string $value
249
     *
250
     * @return static
251
     */
252 5
    public function errorTag(string $value): static
253
    {
254 5
        $new = clone $this;
255 5
        $new->errorTag = $value;
256 5
        return $new;
257
    }
258
259
    /**
260
     * Set hint message for the field.
261
     *
262
     * @param string|null $value
263
     *
264
     * @return static
265
     */
266 3
    public function hint(?string $value): static
267
    {
268 3
        $new = clone $this;
269 3
        $new->hint = $value;
270 3
        return $new;
271
    }
272
273
    /**
274
     * Set hint attributes.
275
     *
276
     * @param array $values Attribute values indexed by attribute names.
277
     *
278
     * ```php
279
     * ['class' => 'test-class']
280
     * ```
281
     *
282
     * @return static The field widget instance.
283
     */
284 3
    public function hintAttributes(array $values): static
285
    {
286 3
        $new = clone $this;
287 3
        $new->hintAttributes = $values;
288 3
        return $new;
289
    }
290
291
    /**
292
     * Set hint css class.
293
     *
294
     * @param string $value
295
     *
296
     * @return static
297
     */
298 8
    public function hintClass(string $value): static
299
    {
300 8
        $new = clone $this;
301 8
        $new->hintClass = $value;
302 8
        return $new;
303
    }
304
305
    /**
306
     * Set hint tag name.
307
     *
308
     * @param string $value
309
     *
310
     * @return static
311
     */
312 3
    public function hintTag(string $value): static
313
    {
314 3
        $new = clone $this;
315 3
        $new->hintTag = $value;
316 3
        return $new;
317
    }
318
319
    /**
320
     * Set input css class.
321
     *
322
     * @param string $value
323
     *
324
     * @return static
325
     */
326 6
    public function inputClass(string $value): static
327
    {
328 6
        $new = clone $this;
329 6
        $new->inputClass = $value;
330 6
        return $new;
331
    }
332
333
    /**
334
     * Set invalid css class.
335
     *
336
     * @param string $value
337
     *
338
     * @return static
339
     */
340 8
    public function invalidClass(string $value): static
341
    {
342 8
        $new = clone $this;
343 8
        $new->invalidClass = $value;
344 8
        return $new;
345
    }
346
347
    /**
348
     * Set label message for the field.
349
     *
350
     * @param string|null $value
351
     *
352
     * @return static
353
     */
354 8
    public function label(?string $value): static
355
    {
356 8
        $new = clone $this;
357 8
        $new->label = $value;
358 8
        return $new;
359
    }
360
361
    /**
362
     * Set label attributes.
363
     *
364
     * @param array $values Attribute values indexed by attribute names.
365
     *
366
     * ```php
367
     * ['class' => 'test-class']
368
     * ```
369
     *
370
     * @return static The field widget instance.
371
     */
372 3
    public function labelAttributes(array $values): static
373
    {
374 3
        $new = clone $this;
375 3
        $new->labelAttributes = $values;
376 3
        return $new;
377
    }
378
379
    /**
380
     * Set the label css class.
381
     *
382
     * @param string $value
383
     *
384
     * @return static
385
     */
386 5
    public function labelClass(string $value): static
387
    {
388 5
        $new = clone $this;
389 5
        $new->labelClass = $value;
390 5
        return $new;
391
    }
392
393
    /**
394
     * The id of a label-able form-related element in the same document as the tag label element.
395
     *
396
     * The first element in the document with an id matching the value of the for attribute is the labeled control for
397
     * this label element, if it is a label-able element.
398
     *
399
     * @param string|null $value The id of a label-able form-related element in the same document as the tag label
400
     * element. If null, the attribute will be removed.
401
     *
402
     * @return static
403
     */
404 2
    public function labelFor(?string $value): static
405
    {
406 2
        $new = clone $this;
407 2
        $new->labelAttributes['for'] = $value;
408 2
        return $new;
409
    }
410
411
    /**
412
     * It allows defining placeholder.
413
     *
414
     * @param string $value
415
     *
416
     * @return static
417
     *
418
     * @link https://html.spec.whatwg.org/multipage/input.html#the-placeholder-attribute
419
     */
420 11
    public function placeholder(string $value): static
421
    {
422 11
        $new = clone $this;
423 11
        $new->placeholder = $value;
424 11
        return $new;
425
    }
426
427
    /**
428
     * A Boolean attribute which, if present, means this field cannot be edited by the user.
429
     * Its value can, however, still be changed by JavaScript code directly setting the HTMLInputElement.value
430
     * property.
431
     *
432
     * @param bool $value
433
     *
434
     * @return static
435
     *
436
     * @link https://html.spec.whatwg.org/multipage/input.html#the-readonly-attribute
437
     */
438 11
    public function readonly(bool $value = true): static
439
    {
440 11
        $new = clone $this;
441 11
        $new->attributes['readonly'] = $value;
442 11
        return $new;
443
    }
444
445
    /**
446
     * Replace individual one token for current field instance.
447
     *
448
     * @param string $token
449
     * @param string|Stringable $value
450
     *
451
     * @return static
452
     */
453 2
    public function replaceIndividualToken(string $token, string|Stringable $value): static
454
    {
455 2
        $new = clone $this;
456 2
        $new->defaultTokens[$token] = $value;
457 2
        return $new;
458
    }
459
460
    /**
461
     * If it is required to fill in a value in order to submit the form.
462
     *
463
     * @return static
464
     *
465
     * @link https://www.w3.org/TR/html52/sec-forms.html#the-required-attribute
466
     */
467 16
    public function required(): static
468
    {
469 16
        $new = clone $this;
470 16
        $new->attributes['required'] = true;
471 16
        return $new;
472
    }
473
474
    /**
475
     * Set layout template for render a field.
476
     *
477
     * @param string $value
478
     *
479
     * @return static
480
     */
481 6
    public function template(string $value): static
482
    {
483 6
        $new = clone $this;
484 6
        $new->template = $value;
485 6
        return $new;
486
    }
487
488
    /**
489
     * Set the value valid css class.
490
     *
491
     * @param string $value is the valid css class.
492
     *
493
     * @return static
494
     */
495 8
    public function validClass(string $value): static
496
    {
497 8
        $new = clone $this;
498 8
        $new->validClass = $value;
499 8
        return $new;
500
    }
501
502
    /**
503
     * Return aria described by field.
504
     *
505
     * if aria described by is not set, and aria described by default is set, then return aria described by default.
506
     *
507
     * @return bool|null
508
     */
509 380
    protected function getAriaDescribedBy(): ?bool
510
    {
511 380
        $ariaDescribedBy = $this->ariaDescribedBy;
512 380
        $ariaDescribedByDefault = $this->getDefaultValue($this->type, 'ariaDescribedBy');
513
514 380
        if (is_bool($ariaDescribedByDefault)) {
515 1
            $ariaDescribedBy = $ariaDescribedByDefault;
516
        }
517
518 380
        return $ariaDescribedBy;
519
    }
520
521
    /**
522
     * Return attributes for field.
523
     *
524
     * if attributes is empty string, and attributes default value is not empty string, then return attributes default
525
     * value.
526
     *
527
     * @return array
528
     */
529 430
    protected function getAttributes(): array
530
    {
531 430
        $attributes = $this->attributes;
532 430
        $attributesDefault = $this->getDefaultValue($this->type, 'attributes');
533
534 430
        return match (is_array($attributesDefault) && $attributesDefault !== []) {
535 3
            true => $attributesDefault,
536 430
            false => $attributes,
537
        };
538
    }
539
540
    /**
541
     * Return enabled, disabled container for field.
542
     *
543
     * if container is not set, and container default value is bool, then return container default value.
544
     *
545
     * @return bool|null
546
     */
547 412
    protected function getContainer(): ?bool
548
    {
549 412
        $container = $this->container;
550 412
        $containerDefault = $this->getDefaultValue($this->type, 'container');
551
552 412
        if (is_bool($containerDefault)) {
553 2
            $container = $containerDefault;
554
        }
555
556 412
        return $container ?? true;
557
    }
558
559
    /**
560
     * Return attributes for container for field.
561
     *
562
     * if attributes container is empty array, and attributes container default value is not empty array, then return
563
     * attributes container default value.
564
     *
565
     * @return array
566
     */
567 412
    protected function getContainerAttributes(): array
568
    {
569 412
        $containerAttributes = $this->containerAttributes;
570 412
        $containerDefaultAttributes = $this->getDefaultValue($this->type, 'containerAttributes');
571
572 412
        return match (is_array($containerDefaultAttributes) && $containerDefaultAttributes !== []) {
573 3
            true => $containerDefaultAttributes,
574 412
            false => $containerAttributes,
575
        };
576
    }
577
578
    /**
579
     * Return class for container field.
580
     *
581
     * if container class is empty string, and container class default value is not empty string, then return container
582
     * class default value.
583
     *
584
     * @return string
585
     */
586 412
    protected function getContainerClass(): string
587
    {
588 412
        $containerClass = $this->containerClass;
589 412
        $containerDefaultClass = $this->getDefaultValue($this->type, 'containerClass');
590
591 412
        return match (is_string($containerDefaultClass) && $containerDefaultClass !== '') {
592 4
            true => $containerDefaultClass,
593 412
            false => $containerClass,
594
        };
595
    }
596
597
    /**
598
     * Return default tokens.
599
     *
600
     * The value is used in case tokens array is empty.
601
     */
602 362
    protected function getDefaultTokens(): array
603
    {
604 362
        $defaultTokens = $this->defaultTokens;
605 362
        $defaultTokensDefault = $this->getDefaultValue($this->type, 'defaultTokens');
606
607 362
        return match (is_array($defaultTokensDefault) && $defaultTokensDefault !== []) {
608 1
            true => $defaultTokensDefault,
609 362
            false => $defaultTokens,
610
        };
611
    }
612
613
    /**
614
     * Return definition for field.
615
     */
616 433
    protected function getDefinitions(): array
617
    {
618 433
        $definitions = $this->getDefaultValue($this->type, 'definitions') ?? [];
619 433
        return  is_array($definitions) ? $definitions : [];
620
    }
621
622
    /**
623
     * Return error message for the field.
624
     *
625
     * if error message is empty string, and error message default value is not empty string, then return error message
626
     * default value.
627
     *
628
     * @return string|null
629
     */
630 358
    protected function getError(): ?string
631
    {
632 358
        $error = $this->error;
633 358
        $errorDefault = $this->getDefaultValue($this->type, 'error');
634
635 358
        return match (is_string($errorDefault) && $errorDefault !== '') {
636 1
            true => $errorDefault,
637 358
            false => $error,
638
        };
639
    }
640
641
    /**
642
     * Return error attribute for the field.
643
     *
644
     * if error attribute is empty string, and error attribute default value is not empty string, then return error
645
     * attribute default value.
646
     *
647
     * @return array
648
     */
649 357
    protected function getErrorAttributes(): array
650
    {
651 357
        $errorAttributes = $this->errorAttributes;
652 357
        $errorAttributesDefault = $this->getDefaultValue($this->type, 'errorAttributes');
653
654 357
        return match (is_array($errorAttributesDefault) && $errorAttributesDefault !== []) {
655 3
            true => $errorAttributesDefault,
656 357
            false => $errorAttributes,
657
        };
658
    }
659
660
    /**
661
     * Return error class for the field.
662
     *
663
     * if error class is empty string, and error class default value is not empty string, then return error class
664
     * default value.
665
     *
666
     * @return string
667
     */
668 357
    protected function getErrorClass(): string
669
    {
670 357
        $errorClass = $this->errorClass;
671 357
        $errorClassDefault = $this->getDefaultValue($this->type, 'errorClass');
672
673 357
        return match (is_string($errorClassDefault) && $errorClassDefault !== '') {
674 3
            true => $errorClassDefault,
675 357
            false => $errorClass,
676
        };
677
    }
678
679
    /**
680
     * Return error message callback for the field.
681
     *
682
     * if error message callback is empty array, and error message callback default value is not empty array, then
683
     * return error message callback default value.
684
     */
685 357
    protected function getErrorMessageCallback(): array
686
    {
687 357
        $errorMessageCallback = $this->errorMessageCallback;
688 357
        $errorMessageCallbackDefault = $this->getDefaultValue($this->type, 'errorMessageCallback');
689
690 357
        return match (is_array($errorMessageCallbackDefault) && $errorMessageCallbackDefault !== []) {
691 1
            true => $errorMessageCallbackDefault,
692 357
            false => $errorMessageCallback,
693
        };
694
    }
695
696
    /**
697
     * Return error tag for the field.
698
     *
699
     * if error tag is empty string, and error tag default value is not empty string, then return error tag default
700
     * value.
701
     *
702
     * @return string
703
     */
704 357
    protected function getErrorTag(): string
705
    {
706 357
        $errorTag = $this->errorTag;
707 357
        $errorTagDefault = $this->getDefaultValue($this->type, 'errorTag');
708
709 357
        return match (is_string($errorTagDefault) && $errorTagDefault !== '') {
710 2
            true => $errorTagDefault,
711 357
            false => $errorTag === '' ? 'div' : $errorTag,
712
        };
713
    }
714
715
    /**
716
     * Return hint for field.
717
     *
718
     * if hint is empty string, and hint default value is not empty string, then return hint default value.
719
     *
720
     * @return string|null
721
     */
722 358
    protected function getHint(): ?string
723
    {
724 358
        $hint = $this->hint;
725 358
        $hintDefault = $this->getDefaultValue($this->type, 'hint') ?? '';
726
727 358
        return match (is_string($hintDefault) && $hintDefault !== '') {
728 1
            true => $hintDefault,
729 358
            false => $hint,
730
        };
731
    }
732
733
    /**
734
     * Return hint attributes for field.
735
     *
736
     * if hint attributes is empty array, and hint default value is not empty array, then return hint default value.
737
     *
738
     * @return array
739
     */
740 358
    protected function getHintAttributes(): array
741
    {
742 358
        $hintAttributes = $this->hintAttributes;
743 358
        $hintAttributesDefault = $this->getDefaultValue($this->type, 'hintAttributes') ?? [];
744
745 358
        return match (is_array($hintAttributesDefault) && $hintAttributesDefault !== []) {
746 1
            true => $hintAttributesDefault,
747 358
            false => $hintAttributes,
748
        };
749
    }
750
751
    /**
752
     * Return hint class for field.
753
     *
754
     * if hint class is empty string, and hint default value is not empty string, then return hint default value.
755
     *
756
     * @return string
757
     */
758 358
    protected function getHintClass(): string
759
    {
760 358
        $hintClass = $this->hintClass;
761 358
        $hintClassDefault = $this->getDefaultValue($this->type, 'hintClass') ?? '';
762
763 358
        return match (is_string($hintClassDefault) && $hintClassDefault !== '') {
764 2
            true => $hintClassDefault,
765 358
            false => $hintClass,
766
        };
767
    }
768
769
    /**
770
     * Return hint tag for field.
771
     *
772
     * if hint tag is empty string, and hint default value is not empty string, then return hint default value.
773
     *
774
     * @return string
775
     */
776 358
    protected function getHintTag(): string
777
    {
778 358
        $hintTag = $this->hintTag;
779 358
        $hintTagDefault = $this->getDefaultValue($this->type, 'hintTag') ?? '';
780
781 358
        return match (is_string($hintTagDefault) && $hintTagDefault !== '') {
782 1
            true => $hintTagDefault,
783 358
            false => $hintTag === '' ? 'div' : $hintTag,
784
        };
785
    }
786
787
    /**
788
     * Return input class for field.
789
     *
790
     * if input class is empty string, and input class default value is not empty string, then return input class
791
     * default value.
792
     *
793
     * @return string
794
     */
795 380
    protected function getInputClass(): string
796
    {
797 380
        $inputClass = $this->inputClass;
798 380
        $inputClassDefault = $this->getDefaultValue($this->type, 'inputClass');
799
800 380
        return match (is_string($inputClassDefault) && $inputClassDefault !== '') {
801 2
            true => $inputClassDefault,
802 380
            false => $inputClass,
803
        };
804
    }
805
806
    /**
807
     * Return invalid class for field.
808
     *
809
     * if invalid class is empty string, and invalid class default value is not empty string, then return invalid class
810
     * default value.
811
     *
812
     * @return string
813
     */
814 380
    protected function getInvalidClass(): string
815
    {
816 380
        $invalidClass = $this->invalidClass;
817 380
        $invalidClassDefault = $this->getDefaultValue($this->type, 'invalidClass');
818
819 380
        return match (is_string($invalidClassDefault) && $invalidClassDefault !== '') {
820 2
            true => $invalidClassDefault,
821 380
            false => $invalidClass,
822
        };
823
    }
824
825
    /**
826
     * Return label for field.
827
     *
828
     * if label is empty string, and label default value is not empty string, then return label default value.
829
     *
830
     * @return string|null
831
     */
832 326
    protected function getLabel(): ?string
833
    {
834 326
        $label = $this->label;
835 326
        $labelDefault = $this->getDefaultValue($this->type, 'label') ?? '';
836
837 326
        return match (is_string($labelDefault) && $labelDefault !== '') {
838 1
            true => $labelDefault,
839 326
            false => $label,
840
        };
841
    }
842
843
    /**
844
     * Return label attributes for field.
845
     *
846
     * if label attributes is empty array, and label attributes default value is not empty array, then return label
847
     * attributes default value.
848
     *
849
     * @return array
850
     */
851 326
    protected function getLabelAttributes(): array
852
    {
853 326
        $labelAttributes = $this->labelAttributes;
854 326
        $labelAttributesDefault = $this->getDefaultValue($this->type, 'labelAttributes') ?? [];
855
856 326
        return match (is_array($labelAttributesDefault) && $labelAttributesDefault !== []) {
857 1
            true => $labelAttributesDefault,
858 326
            false => $labelAttributes,
859
        };
860
    }
861
862
    /**
863
     * Return label css class for field.
864
     *
865
     * if label css class is empty string, and label css class default value is not null, then return label css class
866
     * default value.
867
     *
868
     * @return string
869
     */
870 326
    protected function getLabelClass(): string
871
    {
872 326
        $labelClass = $this->labelClass;
873 326
        $labelClassDefault = $this->getDefaultValue($this->type, 'labelClass') ?? '';
874
875 326
        return match (is_string($labelClassDefault) && $labelClassDefault !== '') {
876 1
            true => $labelClassDefault,
877 326
            false => $labelClass,
878
        };
879
    }
880
881
    /**
882
     * Return placeholder for field.
883
     *
884
     * if placeholder is empty string, and placeholder default value is not empty string, then return placeholder
885
     * default value.
886
     *
887
     * @return string|null
888
     */
889 380
    protected function getPlaceholder(): ?string
890
    {
891 380
        $placeholder = $this->placeholder;
892 380
        $placeholderDefault = $this->getDefaultValue($this->type, 'placeholder') ?? '';
893
894 380
        return match (is_string($placeholderDefault) && $placeholderDefault !== '') {
895 1
            true => $placeholderDefault,
896 380
            false => $placeholder,
897
        };
898
    }
899
900
    /**
901
     * Return template for field.
902
     *
903
     * if template is empty string, and template default value is not empty string, then return template default value.
904
     *
905
     * @return string
906
     */
907 362
    protected function getTemplate(): string
908
    {
909 362
        $template = $this->template;
910 362
        $templateDefault = $this->getDefaultValue($this->type, 'template') ?? '';
911
912 362
        return match (is_string($templateDefault) && $templateDefault !== '') {
913 2
            true => $templateDefault,
914 362
            false => $template === '' ? "{label}\n{input}\n{hint}\n{error}" : $template,
915
        };
916
    }
917
918
    /**
919
     * Return valid class for field.
920
     *
921
     * if valid class is empty string, and valid class default value is not empty string, then return valid class
922
     * default value.
923
     *
924
     * @return string
925
     */
926 380
    protected function getValidClass(): string
927
    {
928 380
        $validClass = $this->validClass;
929 380
        $validDefaultClass = $this->getDefaultValue($this->type, 'validClass') ?? '';
930
931 380
        return match (is_string($validDefaultClass) && $validDefaultClass !== '') {
932 2
            true => $validDefaultClass,
933 380
            false => $validClass,
934
        };
935
    }
936
937
    /**
938
     * Set type class of the field.
939
     *
940
     * @param string $type The type class of the field.
941
     *
942
     * @return static
943
     */
944 434
    protected function type(string $type): static
945
    {
946 434
        $new = clone $this;
947 434
        $new->type = $type;
948 434
        return $new;
949
    }
950
951 433
    private function getDefaultValue(string $type, string $key): array|bool|string|null
952
    {
953
        /** @var array|bool|string|null */
954 433
        return $this->defaultValues[$type][$key] ?? null;
955
    }
956
}
957