Passed
Pull Request — master (#192)
by Sergei
07:08 queued 03:58
created

Range::showOutput()   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 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
c 1
b 0
f 0
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\InputField;
10
use Yiisoft\Html\Html;
11
12
use function is_string;
13
14
/**
15
 * An imprecise control for setting the element’s value to a string representing a number.
16
 *
17
 * @link https://html.spec.whatwg.org/multipage/input.html#range-state-(type=range)
18
 */
19
final class Range extends InputField
20
{
21
    private bool $showOutput = false;
22
23
    /**
24
     * @psalm-var non-empty-string
25
     */
26
    private string $outputTagName = 'span';
27
    private array $outputTagAttributes = [];
28
29
    /**
30
     * Maximum value.
31
     *
32
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-max
33
     */
34 2
    public function max(float|int|string|Stringable|null $value): self
35
    {
36 2
        $new = clone $this;
37 2
        $new->inputTagAttributes['max'] = $value;
38 2
        return $new;
39
    }
40
41
    /**
42
     * Minimum value.
43
     *
44
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-min
45
     */
46 2
    public function min(float|int|string|Stringable|null $value): self
47
    {
48 2
        $new = clone $this;
49 2
        $new->inputTagAttributes['min'] = $value;
50 2
        return $new;
51
    }
52
53
    /**
54
     * Granularity to be matched by the form control's value.
55
     *
56
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-step
57
     */
58
    public function step(float|int|string|Stringable|null $value): self
59
    {
60
        $new = clone $this;
61
        $new->inputTagAttributes['step'] = $value;
62
        return $new;
63
    }
64
65
    /**
66
     * ID of element that lists predefined options suggested to the user.
67
     *
68
     * @link https://html.spec.whatwg.org/multipage/input.html#the-list-attribute
69
     */
70
    public function list(?string $id): self
71
    {
72
        $new = clone $this;
73
        $new->inputTagAttributes['list'] = $id;
74
        return $new;
75
    }
76
77
    /**
78
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
79
     */
80
    public function disabled(bool $disabled = true): self
81
    {
82
        $new = clone $this;
83
        $new->inputTagAttributes['disabled'] = $disabled;
84
        return $new;
85
    }
86
87
    /**
88
     * Identifies the element (or elements) that describes the object.
89
     *
90
     * @link https://w3c.github.io/aria/#aria-describedby
91
     */
92
    public function ariaDescribedBy(string $value): self
93
    {
94
        $new = clone $this;
95
        $new->inputTagAttributes['aria-describedby'] = $value;
96
        return $new;
97
    }
98
99
    /**
100
     * Defines a string value that labels the current element.
101
     *
102
     * @link https://w3c.github.io/aria/#aria-label
103
     */
104
    public function ariaLabel(string $value): self
105
    {
106
        $new = clone $this;
107
        $new->inputTagAttributes['aria-label'] = $value;
108
        return $new;
109
    }
110
111
    /**
112
     * Focus on the control (put cursor into it) when the page loads. Only one form element could be in focus
113
     * at the same time.
114
     *
115
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-fe-autofocus
116
     */
117
    public function autofocus(bool $value = true): self
118
    {
119
        $new = clone $this;
120
        $new->inputTagAttributes['autofocus'] = $value;
121
        return $new;
122
    }
123
124
    /**
125
     * The `tabindex` attribute indicates that its element can be focused, and where it participates in sequential
126
     * keyboard navigation (usually with the Tab key, hence the name).
127
     *
128
     * It accepts an integer as a value, with different results depending on the integer's value:
129
     *
130
     * - A negative value (usually `tabindex="-1"`) means that the element is not reachable via sequential keyboard
131
     *   navigation, but could be focused with Javascript or visually. It's mostly useful to create accessible widgets
132
     *   with JavaScript.
133
     * - `tabindex="0"` means that the element should be focusable in sequential keyboard navigation, but its order is
134
     *   defined by the document's source order.
135
     * - A positive value means the element should be focusable in sequential keyboard navigation, with its order
136
     *   defined by the value of the number. That is, `tabindex="4"` is focused before `tabindex="5"`, but after
137
     *   `tabindex="3"`.
138
     *
139
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
140
     */
141
    public function tabIndex(?int $value): self
142
    {
143
        $new = clone $this;
144
        $new->inputTagAttributes['tabindex'] = $value;
145
        return $new;
146
    }
147
148 1
    public function showOutput(bool $show = true): self
149
    {
150 1
        $new = clone $this;
151 1
        $new->showOutput = $show;
152 1
        return $new;
153
    }
154
155
    public function outputTagName(string $tagName): self
156
    {
157
        if ($tagName === '') {
158
            throw new InvalidArgumentException('The output tag name it cannot be empty value.');
159
        }
160
161
        $new = clone $this;
162
        $new->outputTagName = $tagName;
163
        return $new;
164
    }
165
166 1
    public function outputTagAttributes(array $attributes): self
167
    {
168 1
        $new = clone $this;
169 1
        $new->outputTagAttributes = $attributes;
170 1
        return $new;
171
    }
172
173 2
    protected function generateInput(): string
174
    {
175 2
        $value = $this->getAttributeValue();
176
177 2
        if (!is_string($value) && !is_numeric($value) && $value !== null) {
178
            throw new InvalidArgumentException('Range widget requires a string, numeric or null value.');
179
        }
180
181 2
        $tag = Html::range($this->getInputName(), $value, $this->getInputTagAttributes());
182 2
        if ($this->showOutput) {
183 1
            $tag = $tag
184 1
                ->showOutput()
185 1
                ->outputTagName($this->outputTagName)
186 1
                ->outputTagAttributes($this->outputTagAttributes);
187
        }
188
189 2
        return $tag->render();
190
    }
191
}
192