Passed
Push — master ( 6b3bd5...b249fa )
by Sergei
05:31 queued 02:48
created

Number   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Test Coverage

Coverage 98.28%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 48
c 1
b 0
f 0
dl 0
loc 171
ccs 57
cts 58
cp 0.9828
rs 10
wmc 17

14 Methods

Rating   Name   Duplication   Size   Complexity  
A required() 0 5 1
A step() 0 5 1
A disabled() 0 5 1
A min() 0 5 1
A max() 0 5 1
A readonly() 0 5 1
A ariaLabel() 0 5 1
A tabIndex() 0 5 1
A autofocus() 0 5 1
A ariaDescribedBy() 0 5 1
A prepareContainerAttributes() 0 3 1
A prepareInputAttributes() 0 4 1
A generateInput() 0 15 3
A beforeRender() 0 5 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Field;
6
7
use InvalidArgumentException;
8
use Stringable;
9
use Yiisoft\Form\Field\Base\EnrichFromValidationRules\EnrichFromValidationRulesInterface;
10
use Yiisoft\Form\Field\Base\EnrichFromValidationRules\EnrichFromValidationRulesTrait;
11
use Yiisoft\Form\Field\Base\InputField;
12
use Yiisoft\Form\Field\Base\Placeholder\PlaceholderInterface;
13
use Yiisoft\Form\Field\Base\Placeholder\PlaceholderTrait;
14
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassInterface;
15
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassTrait;
16
use Yiisoft\Form\ThemeContainer;
17
use Yiisoft\Html\Html;
18
19
/**
20
 * Represents `<input>` element of type "number" are used to let the user enter and edit a telephone number.
21
 *
22
 * @link https://html.spec.whatwg.org/multipage/input.html#number-state-(type=number)
23
 * @link https://developer.mozilla.org/docs/Web/HTML/Element/input/number
24
 */
25
final class Number extends InputField implements EnrichFromValidationRulesInterface, PlaceholderInterface, ValidationClassInterface
26
{
27
    use EnrichFromValidationRulesTrait;
28
    use PlaceholderTrait;
29
    use ValidationClassTrait;
30
31
    /**
32
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-max
33
     */
34 6
    public function max(int|float|string|Stringable|null $value): self
35
    {
36 6
        $new = clone $this;
37 6
        $new->inputAttributes['max'] = $value;
38 6
        return $new;
39
    }
40
41
    /**
42
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-min
43
     */
44 6
    public function min(int|float|string|Stringable|null $value): self
45
    {
46 6
        $new = clone $this;
47 6
        $new->inputAttributes['min'] = $value;
48 6
        return $new;
49
    }
50
51
    /**
52
     * Granularity to be matched by the form control's value.
53
     *
54
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-step
55
     */
56 6
    public function step(float|int|string|Stringable|null $value): self
57
    {
58 6
        $new = clone $this;
59 6
        $new->inputAttributes['step'] = $value;
60 6
        return $new;
61
    }
62
63
    /**
64
     * A boolean attribute that controls whether or not the user can edit the form control.
65
     *
66
     * @param bool $value Whether to allow the value to be edited by the user.
67
     *
68
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-readonly
69
     */
70 2
    public function readonly(bool $value = true): self
71
    {
72 2
        $new = clone $this;
73 2
        $new->inputAttributes['readonly'] = $value;
74 2
        return $new;
75
    }
76
77
    /**
78
     * A boolean attribute. When specified, the element is required.
79
     *
80
     * @param bool $value Whether the control is required for form submission.
81
     *
82
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-required
83
     */
84 2
    public function required(bool $value = true): self
85
    {
86 2
        $new = clone $this;
87 2
        $new->inputAttributes['required'] = $value;
88 2
        return $new;
89
    }
90
91
    /**
92
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
93
     */
94 2
    public function disabled(bool $disabled = true): self
95
    {
96 2
        $new = clone $this;
97 2
        $new->inputAttributes['disabled'] = $disabled;
98 2
        return $new;
99
    }
100
101
    /**
102
     * Identifies the element (or elements) that describes the object.
103
     *
104
     * @link https://w3c.github.io/aria/#aria-describedby
105
     */
106 2
    public function ariaDescribedBy(?string $value): self
107
    {
108 2
        $new = clone $this;
109 2
        $new->inputAttributes['aria-describedby'] = $value;
110 2
        return $new;
111
    }
112
113
    /**
114
     * Defines a string value that labels the current element.
115
     *
116
     * @link https://w3c.github.io/aria/#aria-label
117
     */
118 2
    public function ariaLabel(?string $value): self
119
    {
120 2
        $new = clone $this;
121 2
        $new->inputAttributes['aria-label'] = $value;
122 2
        return $new;
123
    }
124
125
    /**
126
     * Focus on the control (put cursor into it) when the page loads. Only one form element could be in focus
127
     * at the same time.
128
     *
129
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-fe-autofocus
130
     */
131 2
    public function autofocus(bool $value = true): self
132
    {
133 2
        $new = clone $this;
134 2
        $new->inputAttributes['autofocus'] = $value;
135 2
        return $new;
136
    }
137
138
    /**
139
     * The `tabindex` attribute indicates that its element can be focused, and where it participates in sequential
140
     * keyboard navigation (usually with the Tab key, hence the name).
141
     *
142
     * It accepts an integer as a value, with different results depending on the integer's value:
143
     *
144
     * - A negative value (usually `tabindex="-1"`) means that the element is not reachable via sequential keyboard
145
     *   navigation, but could be focused with Javascript or visually. It's mostly useful to create accessible widgets
146
     *   with JavaScript.
147
     * - `tabindex="0"` means that the element should be focusable in sequential keyboard navigation, but its order is
148
     *   defined by the document's source order.
149
     * - A positive value means the element should be focusable in sequential keyboard navigation, with its order
150
     *   defined by the value of the number. That is, `tabindex="4"` is focused before `tabindex="5"`, but after
151
     *   `tabindex="3"`.
152
     *
153
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
154
     */
155 2
    public function tabIndex(?int $value): self
156
    {
157 2
        $new = clone $this;
158 2
        $new->inputAttributes['tabindex'] = $value;
159 2
        return $new;
160
    }
161
162 24
    protected function beforeRender(): void
163
    {
164 24
        parent::beforeRender();
165 24
        if ($this->enrichFromValidationRules) {
166
            $this->enrichment = ThemeContainer::getEnrichment($this, $this->getInputData());
167
        }
168
    }
169
170 24
    protected function generateInput(): string
171
    {
172 24
        $value = $this->getValue();
173
174 24
        if (!is_numeric($value) && $value !== null) {
175 1
            throw new InvalidArgumentException('Number field requires a numeric or null value.');
176
        }
177
178
        /** @psalm-suppress MixedArgument We guess that enrichment contain correct values. */
179 23
        $inputAttributes = array_merge(
180 23
            $this->enrichment['inputAttributes'] ?? [],
181 23
            $this->getInputAttributes()
182 23
        );
183
184 23
        return Html::input('number', $this->getName(), $value, $inputAttributes)->render();
185
    }
186
187 8
    protected function prepareContainerAttributes(array &$attributes): void
188
    {
189 8
        $this->addValidationClassToAttributes($attributes, $this->getInputData());
190
    }
191
192 23
    protected function prepareInputAttributes(array &$attributes): void
193
    {
194 23
        $this->preparePlaceholderInInputAttributes($attributes);
195 23
        $this->addInputValidationClassToAttributes($attributes, $this->getInputData());
196
    }
197
}
198