@rak200/ui 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -18
- package/dist/field.d.ts +5 -3
- package/dist/field.d.ts.map +1 -1
- package/dist/field.js +5 -3
- package/dist/field.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +330 -33
- package/dist/input.d.ts.map +1 -1
- package/dist/input.js +355 -64
- package/dist/input.js.map +1 -1
- package/dist/select.d.ts +220 -14
- package/dist/select.d.ts.map +1 -1
- package/dist/select.js +381 -26
- package/dist/select.js.map +1 -1
- package/package.json +1 -1
package/dist/input.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LitElement, css, html } from 'lit';
|
|
1
|
+
import { LitElement, css, html, nothing } from 'lit';
|
|
2
2
|
import { reference } from './reference.js';
|
|
3
3
|
/**
|
|
4
4
|
* What a styled native control looks like, which both elements share.
|
|
@@ -6,24 +6,32 @@ import { reference } from './reference.js';
|
|
|
6
6
|
* One stylesheet naming both `input` and `textarea` rather than one per element: the two
|
|
7
7
|
* differ in what they accept and in one rule about resizing, and duplicating the whole
|
|
8
8
|
* box to express that would be two copies of a contract with nothing comparing them.
|
|
9
|
+
*
|
|
10
|
+
* **Every rule reaches a control this element renders**, which RFC 0005 decided. The
|
|
11
|
+
* `::slotted()` these rules were written with was forced by the control having to sit in
|
|
12
|
+
* the host's tree, where the label could reach it — and what a relationship actually needs
|
|
13
|
+
* is for every end of it to share a tree scope, which a `<label for>` and its control in
|
|
14
|
+
* one shadow root satisfy. So the label, the help and the error came inside with it.
|
|
9
15
|
*/
|
|
10
|
-
const
|
|
16
|
+
const field = css `
|
|
11
17
|
:host {
|
|
12
18
|
display: block;
|
|
19
|
+
font-family: ${reference('--ui-font')};
|
|
13
20
|
}
|
|
14
21
|
|
|
15
|
-
/*
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
/* The rhythm ui-field used to own, now owned by the control it was wrapping. */
|
|
23
|
+
.stack {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
gap: calc(${reference('--ui-space')} / 2);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
label {
|
|
30
|
+
color: ${reference('--ui-color-text')};
|
|
31
|
+
}
|
|
21
32
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
should not work. */
|
|
25
|
-
::slotted(input),
|
|
26
|
-
::slotted(textarea) {
|
|
33
|
+
input,
|
|
34
|
+
textarea {
|
|
27
35
|
box-sizing: border-box;
|
|
28
36
|
inline-size: 100%;
|
|
29
37
|
font: inherit;
|
|
@@ -40,8 +48,8 @@ const control = css `
|
|
|
40
48
|
${reference('--ui-easing-state')};
|
|
41
49
|
}
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
input::placeholder,
|
|
52
|
+
textarea::placeholder {
|
|
45
53
|
color: ${reference('--ui-color-text-muted')};
|
|
46
54
|
/* Firefox lowers a placeholder's opacity by default, which would take the colour
|
|
47
55
|
below the 4.5:1 it was chosen to clear — a contrast floor undone by a rule
|
|
@@ -56,98 +64,381 @@ const control = css `
|
|
|
56
64
|
The guards are measured rather than assumed, the same way ui-button's are: a
|
|
57
65
|
disabled control still matches :hover, and a readonly one accepts a pointer it will
|
|
58
66
|
do nothing with. */
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
input:hover:not(:disabled):not([readonly]),
|
|
68
|
+
textarea:hover:not(:disabled):not([readonly]) {
|
|
61
69
|
border-color: ${reference('--ui-color-text')};
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
/* A visible focus ring is not decoration: removing it is the single most common way a
|
|
65
73
|
component stops being usable by keyboard. */
|
|
66
|
-
|
|
67
|
-
|
|
74
|
+
input:focus-visible,
|
|
75
|
+
textarea:focus-visible {
|
|
68
76
|
outline: 2px solid ${reference('--ui-color-focus')};
|
|
69
77
|
outline-offset: 2px;
|
|
70
78
|
}
|
|
71
79
|
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
input:disabled,
|
|
81
|
+
textarea:disabled {
|
|
74
82
|
cursor: not-allowed;
|
|
75
83
|
opacity: 0.5;
|
|
76
84
|
}
|
|
77
85
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
:host([disabled]) label {
|
|
87
|
+
color: ${reference('--ui-color-text-muted')};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Read off the control's own aria-invalid rather than off a host attribute: it is the
|
|
91
|
+
same source a screen reader uses, and it is the rule this file already carried when
|
|
92
|
+
ui-field was the one writing it. Not :host([error]) — a reflected string property
|
|
93
|
+
whose default is empty puts an empty attribute on the host, and an
|
|
94
|
+
attribute-presence selector matches every element. Measured on ui-checkbox. */
|
|
95
|
+
input[aria-invalid='true'],
|
|
96
|
+
textarea[aria-invalid='true'] {
|
|
85
97
|
border-color: ${reference('--ui-color-danger')};
|
|
86
98
|
}
|
|
99
|
+
|
|
100
|
+
.help {
|
|
101
|
+
color: ${reference('--ui-color-text')};
|
|
102
|
+
font-size: ${reference('--ui-text-supporting')};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* Colour is not the only cue — the message says what is wrong, and aria-invalid marks
|
|
106
|
+
the control whatever the styling does. */
|
|
107
|
+
.error {
|
|
108
|
+
color: ${reference('--ui-color-danger')};
|
|
109
|
+
font-size: ${reference('--ui-text-supporting')};
|
|
110
|
+
}
|
|
87
111
|
`;
|
|
88
112
|
/**
|
|
89
|
-
*
|
|
113
|
+
* Omitted rather than written blank, which is a rule and not a preference.
|
|
90
114
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
115
|
+
* An empty attribute is not a neutral one: `pattern=""` is the empty expression and
|
|
116
|
+
* matches only the empty string, so a field carrying it is invalid for every value a
|
|
117
|
+
* person can type. Measured, as a control that reported `patternMismatch` with no pattern
|
|
118
|
+
* in sight. The same shape bit `<ui-checkbox>` from the other side, where `error=""`
|
|
119
|
+
* matched an attribute-presence selector on every element.
|
|
94
120
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return html `<slot></slot>`;
|
|
98
|
-
}
|
|
121
|
+
function attribute(value) {
|
|
122
|
+
return value === '' ? nothing : value;
|
|
99
123
|
}
|
|
100
124
|
/**
|
|
101
|
-
* A
|
|
125
|
+
* A styled native form control, and the wiring that used to sit around it.
|
|
126
|
+
*
|
|
127
|
+
* **The control is this element's**, rendered into its shadow root together with its
|
|
128
|
+
* label, its help text and its message — so the IDREFs resolve in one tree scope and
|
|
129
|
+
* `<ui-field>` has nothing left to point at. What a host writes is the tag and its
|
|
130
|
+
* attributes.
|
|
102
131
|
*
|
|
103
|
-
* **The
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
|
|
132
|
+
* **The element is the form control**, through `ElementInternals`: an `<input>` in a
|
|
133
|
+
* shadow root has no form owner, so the value reaches a submit because this element passes
|
|
134
|
+
* it on. **Constraint validation is not reimplemented** — the inner control still computes
|
|
135
|
+
* its own, `type="email"` and `min` and `pattern` included, and this element hands the
|
|
136
|
+
* whole `ValidityState` over with the message the engine wrote. Measured: a bad address
|
|
137
|
+
* reports `typeMismatch` with the browser's own wording.
|
|
138
|
+
*/
|
|
139
|
+
class UiTextField extends LitElement {
|
|
140
|
+
constructor() {
|
|
141
|
+
super(...arguments);
|
|
142
|
+
/**
|
|
143
|
+
* The accessible name, and the text above the control.
|
|
144
|
+
*
|
|
145
|
+
* A plain field rather than the `accessor` keyword, for the reason `src/button.ts`
|
|
146
|
+
* gives beside its own — and so for every property below.
|
|
147
|
+
*/
|
|
148
|
+
this.label = '';
|
|
149
|
+
/** Supporting text under the control, which survives an error rather than yielding. */
|
|
150
|
+
this.help = '';
|
|
151
|
+
/** The message, which paints the boundary and is announced with the control. */
|
|
152
|
+
this.error = '';
|
|
153
|
+
/**
|
|
154
|
+
* The name the value is submitted under.
|
|
155
|
+
*
|
|
156
|
+
* **Reflected, and that is a requirement rather than a convenience.** A form names a
|
|
157
|
+
* form-associated custom element's entry from the content attribute, so a host who set
|
|
158
|
+
* only the property would submit nothing at all — silently.
|
|
159
|
+
*/
|
|
160
|
+
this.name = '';
|
|
161
|
+
/**
|
|
162
|
+
* What the control holds.
|
|
163
|
+
*
|
|
164
|
+
* **Not reflected**, the way a native control's `value` IDL attribute is not: the
|
|
165
|
+
* content attribute is the *default* a reset returns to, and one that followed every
|
|
166
|
+
* keystroke would make the default whatever was last typed.
|
|
167
|
+
*/
|
|
168
|
+
this.value = '';
|
|
169
|
+
/** The hint inside an empty control, which is never a substitute for the label. */
|
|
170
|
+
this.placeholder = '';
|
|
171
|
+
/** What the browser may fill this with. Empty means the attribute is not written. */
|
|
172
|
+
this.autocomplete = '';
|
|
173
|
+
/** The shortest accepted value, as the attribute spells it. */
|
|
174
|
+
this.minlength = '';
|
|
175
|
+
/** The longest accepted value, likewise. */
|
|
176
|
+
this.maxlength = '';
|
|
177
|
+
/** Whether a form is invalid while the control is empty. */
|
|
178
|
+
this.required = false;
|
|
179
|
+
/** Whether the control refuses interaction, and submits nothing. */
|
|
180
|
+
this.disabled = false;
|
|
181
|
+
/** Whether the control shows a value it will not let you change. */
|
|
182
|
+
this.readonly = false;
|
|
183
|
+
this.#internals = this.attachInternals();
|
|
184
|
+
/**
|
|
185
|
+
* Mirrors what the person typed back into the property it came from.
|
|
186
|
+
*
|
|
187
|
+
* `input` is composed and leaves the shadow root on its own, retargeted to this
|
|
188
|
+
* element; `change` is not, so the one the control fires stops at the boundary and is
|
|
189
|
+
* re-dispatched. Measured on `<ui-checkbox>`, and the same both times.
|
|
190
|
+
*/
|
|
191
|
+
this.typed = (event) => {
|
|
192
|
+
this.value = event.target.value;
|
|
193
|
+
};
|
|
194
|
+
this.changed = () => {
|
|
195
|
+
this.dispatchEvent(new Event('change', { bubbles: true }));
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
static { this.formAssociated = true; }
|
|
199
|
+
/**
|
|
200
|
+
* Focus is delegated, so `focus()` and `reportValidity()` reach the control.
|
|
201
|
+
*
|
|
202
|
+
* Neither is optional: the host is not a focusable element, and the second is what the
|
|
203
|
+
* browser calls itself when a form with an invalid control is submitted. Measured, on
|
|
204
|
+
* `<ui-checkbox>` first.
|
|
205
|
+
*/
|
|
206
|
+
static { this.shadowRootOptions = {
|
|
207
|
+
...LitElement.shadowRootOptions,
|
|
208
|
+
delegatesFocus: true,
|
|
209
|
+
}; }
|
|
210
|
+
static { this.properties = {
|
|
211
|
+
label: { type: String, reflect: true },
|
|
212
|
+
help: { type: String, reflect: true },
|
|
213
|
+
error: { type: String, reflect: true },
|
|
214
|
+
name: { type: String, reflect: true },
|
|
215
|
+
// Stryker disable next-line ObjectLiteral: `{}` is what Lit's default converter
|
|
216
|
+
// already does for a string — `type` only switches the converter for Boolean,
|
|
217
|
+
// Number, Object and Array — and `reflect` defaults to false either way. The
|
|
218
|
+
// declaration is written out to say which of the two `value` is, not to change it.
|
|
219
|
+
value: { type: String },
|
|
220
|
+
placeholder: { type: String, reflect: true },
|
|
221
|
+
autocomplete: { type: String, reflect: true },
|
|
222
|
+
minlength: { type: String, reflect: true },
|
|
223
|
+
maxlength: { type: String, reflect: true },
|
|
224
|
+
required: { type: Boolean, reflect: true },
|
|
225
|
+
disabled: { type: Boolean, reflect: true },
|
|
226
|
+
readonly: { type: Boolean, reflect: true },
|
|
227
|
+
}; }
|
|
228
|
+
#internals;
|
|
229
|
+
/** The validity, taken from the control that computed it. */
|
|
230
|
+
#publish(control) {
|
|
231
|
+
if (this.error !== '') {
|
|
232
|
+
this.#internals.setValidity({ customError: true }, this.error, control);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
// The whole ValidityState, handed over as the platform computed it — so `min`,
|
|
236
|
+
// `pattern`, `type="email"` and whatever the platform adds next are validated by
|
|
237
|
+
// the thing that already knows how, with the message it already wrote.
|
|
238
|
+
this.#internals.setValidity(control.validity, control.validationMessage, control);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* The value and the validity, which move together here or disagree anywhere.
|
|
242
|
+
*
|
|
243
|
+
* **Iterated rather than asserted**, and there is exactly one control to iterate:
|
|
244
|
+
* `render()` puts it there unconditionally. Written as a query and a null check, the
|
|
245
|
+
* check would be a branch no test could reach — which is a coverage hole and an
|
|
246
|
+
* immortal mutant at once, rather than safety. A loop over what was rendered is total.
|
|
247
|
+
*/
|
|
248
|
+
updated() {
|
|
249
|
+
this.#internals.setFormValue(this.value);
|
|
250
|
+
for (const control of this.renderRoot.querySelectorAll('input, textarea')) {
|
|
251
|
+
this.#publish(control);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* A form reset, which returns to the content attribute — `defaultValue` exactly, and
|
|
256
|
+
* a usable default only because `value` is not reflected onto it.
|
|
257
|
+
*/
|
|
258
|
+
formResetCallback() {
|
|
259
|
+
this.value = this.getAttribute('value') ?? '';
|
|
260
|
+
}
|
|
261
|
+
/** A `<fieldset disabled>` above this element, which reaches it and nothing below. */
|
|
262
|
+
formDisabledCallback(disabled) {
|
|
263
|
+
this.disabled = disabled;
|
|
264
|
+
}
|
|
265
|
+
/** Restoring after a back-navigation, where the browser hands the value back. */
|
|
266
|
+
formStateRestoreCallback(state) {
|
|
267
|
+
this.value = state ?? '';
|
|
268
|
+
}
|
|
269
|
+
/** The form this element participates in, for a host that needs it. */
|
|
270
|
+
get form() {
|
|
271
|
+
return this.#internals.form;
|
|
272
|
+
}
|
|
273
|
+
/** Whether the control currently satisfies its constraints. */
|
|
274
|
+
get validity() {
|
|
275
|
+
return this.#internals.validity;
|
|
276
|
+
}
|
|
277
|
+
/** The message a form would report for it, empty while the control is valid. */
|
|
278
|
+
get validationMessage() {
|
|
279
|
+
return this.#internals.validationMessage;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* The label, the help and the message, with the control between them.
|
|
283
|
+
*
|
|
284
|
+
* The control is passed in rather than produced by an overridable hook, for the reason
|
|
285
|
+
* `src/checkbox.ts` gives at its own: a hook whose base implementation returns a
|
|
286
|
+
* default cannot be told from one that returns nothing, and the mutation floor is what
|
|
287
|
+
* reports the difference.
|
|
288
|
+
*
|
|
289
|
+
* **The error is described before the help**, and the help is not replaced by it: a
|
|
290
|
+
* screen reader announces descriptions in order, and help text is usually the format
|
|
291
|
+
* requirement — which is the very suggestion a reader needs in order to recover
|
|
292
|
+
* (WCAG 3.3.3). `<ui-field>` decided that and this carries it.
|
|
293
|
+
*/
|
|
294
|
+
frame(control) {
|
|
295
|
+
return html `
|
|
296
|
+
<div class="stack" part="stack">
|
|
297
|
+
<label for="control" part="label">${this.label}</label>
|
|
298
|
+
${control}
|
|
299
|
+
${this.help === ''
|
|
300
|
+
? nothing
|
|
301
|
+
: html `<span class="help" id="help" part="help">${this.help}</span>`}
|
|
302
|
+
${this.error === ''
|
|
303
|
+
? nothing
|
|
304
|
+
: html `<span class="error" id="error" part="error">${this.error}</span>`}
|
|
305
|
+
</div>
|
|
306
|
+
`;
|
|
307
|
+
}
|
|
308
|
+
/** The ids describing the control, in the order a reader needs them. */
|
|
309
|
+
described() {
|
|
310
|
+
return attribute([this.error === '' ? '' : 'error', this.help === '' ? '' : 'help']
|
|
311
|
+
.filter((id) => id !== '')
|
|
312
|
+
.join(' '));
|
|
313
|
+
}
|
|
314
|
+
/** Whether the control announces itself as invalid, which the boundary reads. */
|
|
315
|
+
invalid() {
|
|
316
|
+
return this.error === '' ? nothing : 'true';
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* A text input, drawn from the token layer rather than replaced.
|
|
110
321
|
*
|
|
111
|
-
*
|
|
112
|
-
* the label
|
|
322
|
+
* **You write the tag, not a control.** RFC 0005 reversed the rule this element was built
|
|
323
|
+
* on: the `<input>`, its `<label>`, its help text and its message are rendered together in
|
|
324
|
+
* one shadow root, so the IDREFs resolve and there is nothing left for `<ui-field>` to
|
|
325
|
+
* wire. The attributes below are the platform's own, and the ones it computes with —
|
|
326
|
+
* `type`, `pattern`, `min`, `max`, `step` — are handed to a real `<input>` that validates
|
|
327
|
+
* them itself.
|
|
113
328
|
*
|
|
114
329
|
* @example
|
|
115
330
|
* ```html
|
|
116
|
-
* <ui-
|
|
117
|
-
* <label slot="label">Amount</label>
|
|
118
|
-
* <ui-input><input type="number" name="amount" /></ui-input>
|
|
119
|
-
* <span slot="help">In BRL, two decimals.</span>
|
|
120
|
-
* </ui-field>
|
|
331
|
+
* <ui-input label="Amount" help="In BRL, two decimals." type="number" name="amount"></ui-input>
|
|
121
332
|
* ```
|
|
122
333
|
*/
|
|
123
|
-
export class UiInput extends
|
|
124
|
-
|
|
334
|
+
export class UiInput extends UiTextField {
|
|
335
|
+
constructor() {
|
|
336
|
+
super(...arguments);
|
|
337
|
+
/** Which control the platform draws, and which constraints it then applies. */
|
|
338
|
+
this.type = 'text';
|
|
339
|
+
/** Which keyboard a touch device offers, where `type` is not the right lever. */
|
|
340
|
+
this.inputmode = '';
|
|
341
|
+
/** The expression the value must match. Empty means no attribute is written. */
|
|
342
|
+
this.pattern = '';
|
|
343
|
+
/** The lowest accepted value, likewise. */
|
|
344
|
+
this.min = '';
|
|
345
|
+
/** The highest accepted value, likewise. */
|
|
346
|
+
this.max = '';
|
|
347
|
+
/** The granularity the value must fall on, likewise. */
|
|
348
|
+
this.step = '';
|
|
349
|
+
}
|
|
350
|
+
static { this.styles = field; }
|
|
351
|
+
static { this.properties = {
|
|
352
|
+
...UiTextField.properties,
|
|
353
|
+
type: { type: String, reflect: true },
|
|
354
|
+
inputmode: { type: String, reflect: true },
|
|
355
|
+
pattern: { type: String, reflect: true },
|
|
356
|
+
min: { type: String, reflect: true },
|
|
357
|
+
max: { type: String, reflect: true },
|
|
358
|
+
step: { type: String, reflect: true },
|
|
359
|
+
}; }
|
|
360
|
+
render() {
|
|
361
|
+
return this.frame(html `
|
|
362
|
+
<input
|
|
363
|
+
id="control"
|
|
364
|
+
part="control"
|
|
365
|
+
type=${this.type}
|
|
366
|
+
.value=${this.value}
|
|
367
|
+
name=${attribute(this.name)}
|
|
368
|
+
placeholder=${attribute(this.placeholder)}
|
|
369
|
+
autocomplete=${attribute(this.autocomplete)}
|
|
370
|
+
inputmode=${attribute(this.inputmode)}
|
|
371
|
+
pattern=${attribute(this.pattern)}
|
|
372
|
+
minlength=${attribute(this.minlength)}
|
|
373
|
+
maxlength=${attribute(this.maxlength)}
|
|
374
|
+
min=${attribute(this.min)}
|
|
375
|
+
max=${attribute(this.max)}
|
|
376
|
+
step=${attribute(this.step)}
|
|
377
|
+
?required=${this.required}
|
|
378
|
+
?disabled=${this.disabled}
|
|
379
|
+
?readonly=${this.readonly}
|
|
380
|
+
aria-invalid=${this.invalid()}
|
|
381
|
+
aria-describedby=${this.described()}
|
|
382
|
+
@input=${this.typed}
|
|
383
|
+
@change=${this.changed}
|
|
384
|
+
/>
|
|
385
|
+
`);
|
|
386
|
+
}
|
|
125
387
|
}
|
|
126
388
|
/**
|
|
127
|
-
* A multi-line text control,
|
|
389
|
+
* A multi-line text control, drawn from the token layer rather than replaced.
|
|
128
390
|
*
|
|
129
|
-
* Everything {@link UiInput} says applies. What differs is two rules
|
|
130
|
-
* at, and resizing left on the vertical axis
|
|
131
|
-
* fight
|
|
391
|
+
* Everything {@link UiInput} says applies. What differs is two rules — a height to start
|
|
392
|
+
* at, and resizing left on the vertical axis, because a control that cannot grow is one
|
|
393
|
+
* people fight and one that grows sideways breaks the layout around it — and that a
|
|
394
|
+
* `<textarea>` has no `type` and no `pattern` to validate against.
|
|
132
395
|
*
|
|
133
396
|
* @example
|
|
134
397
|
* ```html
|
|
135
|
-
* <ui-
|
|
136
|
-
* <label slot="label">Notes</label>
|
|
137
|
-
* <ui-textarea><textarea name="notes" rows="4"></textarea></ui-textarea>
|
|
138
|
-
* </ui-field>
|
|
398
|
+
* <ui-textarea label="Notes" name="notes" rows="4"></ui-textarea>
|
|
139
399
|
* ```
|
|
140
400
|
*/
|
|
141
|
-
export class UiTextarea extends
|
|
401
|
+
export class UiTextarea extends UiTextField {
|
|
402
|
+
constructor() {
|
|
403
|
+
super(...arguments);
|
|
404
|
+
/** How many lines the control starts at. Empty leaves the platform's own default. */
|
|
405
|
+
this.rows = '';
|
|
406
|
+
}
|
|
142
407
|
static { this.styles = [
|
|
143
|
-
|
|
408
|
+
field,
|
|
144
409
|
css `
|
|
145
|
-
|
|
410
|
+
textarea {
|
|
146
411
|
min-block-size: calc(${reference('--ui-space')} * 10);
|
|
147
412
|
resize: vertical;
|
|
148
413
|
}
|
|
149
414
|
`,
|
|
150
415
|
]; }
|
|
416
|
+
static { this.properties = {
|
|
417
|
+
...UiTextField.properties,
|
|
418
|
+
rows: { type: String, reflect: true },
|
|
419
|
+
}; }
|
|
420
|
+
render() {
|
|
421
|
+
return this.frame(html `
|
|
422
|
+
<textarea
|
|
423
|
+
id="control"
|
|
424
|
+
part="control"
|
|
425
|
+
.value=${this.value}
|
|
426
|
+
name=${attribute(this.name)}
|
|
427
|
+
placeholder=${attribute(this.placeholder)}
|
|
428
|
+
autocomplete=${attribute(this.autocomplete)}
|
|
429
|
+
minlength=${attribute(this.minlength)}
|
|
430
|
+
maxlength=${attribute(this.maxlength)}
|
|
431
|
+
rows=${attribute(this.rows)}
|
|
432
|
+
?required=${this.required}
|
|
433
|
+
?disabled=${this.disabled}
|
|
434
|
+
?readonly=${this.readonly}
|
|
435
|
+
aria-invalid=${this.invalid()}
|
|
436
|
+
aria-describedby=${this.described()}
|
|
437
|
+
@input=${this.typed}
|
|
438
|
+
@change=${this.changed}
|
|
439
|
+
></textarea>
|
|
440
|
+
`);
|
|
441
|
+
}
|
|
151
442
|
}
|
|
152
443
|
// Stryker disable next-line StringLiteral: the registration runs once, at import, inside
|
|
153
444
|
// the warm process Stryker switches mutants in — so by the time a mutant on this line is
|
package/dist/input.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAuC,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"input.js","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"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"}
|