@spectrum-web-components/textfield 0.13.0 → 0.13.2
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/package.json +3 -3
- package/sp-textfield.dev.js +1 -0
- package/sp-textfield.dev.js.map +1 -1
- package/sp-textfield.js +1 -1
- package/sp-textfield.js.map +2 -2
- package/src/Textfield.dev.js +28 -10
- package/src/Textfield.dev.js.map +1 -1
- package/src/Textfield.js +17 -17
- package/src/Textfield.js.map +2 -2
- package/src/index.dev.js +1 -0
- package/src/index.dev.js.map +1 -1
- package/src/index.js +1 -1
- package/src/index.js.map +1 -1
- package/src/spectrum-textfield.css.dev.js +1 -0
- package/src/spectrum-textfield.css.dev.js.map +1 -1
- package/src/spectrum-textfield.css.js +1 -1
- package/src/spectrum-textfield.css.js.map +2 -2
- package/src/textfield.css.dev.js +2 -1
- package/src/textfield.css.dev.js.map +2 -2
- package/src/textfield.css.js +2 -2
- package/src/textfield.css.js.map +3 -3
- package/stories/textarea.stories.js +26 -8
- package/stories/textarea.stories.js.map +1 -1
- package/stories/textfield.stories.js +32 -8
- package/stories/textfield.stories.js.map +1 -1
- package/test/benchmark/test-basic.js +5 -1
- package/test/benchmark/test-basic.js.map +1 -1
- package/test/textarea.test-vrt.js +4 -1
- package/test/textarea.test-vrt.js.map +1 -1
- package/test/textfield.test-vrt.js +4 -1
- package/test/textfield.test-vrt.js.map +1 -1
- package/test/textfield.test.js +611 -60
- package/test/textfield.test.js.map +1 -1
package/test/textfield.test.js
CHANGED
|
@@ -1,45 +1,187 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
import { elementUpdated, expect, html, litFixture } from "@open-wc/testing";
|
|
3
|
+
import { sendKeys } from "@web/test-runner-commands";
|
|
4
|
+
import { sendMouse } from "../../../test/plugins/browser.js";
|
|
5
|
+
import { findDescribedNode } from "../../../test/testing-helpers-a11y.js";
|
|
6
|
+
import "@spectrum-web-components/help-text/sp-help-text.js";
|
|
7
|
+
import "@spectrum-web-components/textfield/sp-textfield.js";
|
|
8
|
+
import { testForLitDevWarnings } from "../../../test/testing-helpers.js";
|
|
9
|
+
describe("Textfield", () => {
|
|
10
|
+
testForLitDevWarnings(
|
|
11
|
+
async () => await litFixture(
|
|
12
|
+
html`
|
|
2
13
|
<sp-textfield label="Enter Your Name"></sp-textfield>
|
|
3
|
-
`
|
|
14
|
+
`
|
|
15
|
+
)
|
|
16
|
+
);
|
|
17
|
+
it("loads default textfield accessibly", async () => {
|
|
18
|
+
const el = await litFixture(
|
|
19
|
+
html`
|
|
4
20
|
<sp-textfield label="Enter Your Name"></sp-textfield>
|
|
5
|
-
`
|
|
21
|
+
`
|
|
22
|
+
);
|
|
23
|
+
await elementUpdated(el);
|
|
24
|
+
await expect(el).to.be.accessible();
|
|
25
|
+
});
|
|
26
|
+
it("loads multiline textfield accessibly", async () => {
|
|
27
|
+
const el = await litFixture(
|
|
28
|
+
html`
|
|
6
29
|
<sp-textfield label="Enter your name" multiline></sp-textfield>
|
|
7
|
-
`
|
|
30
|
+
`
|
|
31
|
+
);
|
|
32
|
+
await elementUpdated(el);
|
|
33
|
+
await expect(el).to.be.accessible();
|
|
34
|
+
});
|
|
35
|
+
it("manages tabIndex while disabled", async () => {
|
|
36
|
+
const el = await litFixture(
|
|
37
|
+
html`
|
|
8
38
|
<sp-textfield placeholder="Enter Your Name"></sp-textfield>
|
|
9
|
-
`
|
|
10
|
-
|
|
11
|
-
|
|
39
|
+
`
|
|
40
|
+
);
|
|
41
|
+
await elementUpdated(el);
|
|
42
|
+
expect(el.tabIndex).to.equal(0);
|
|
43
|
+
el.disabled = true;
|
|
44
|
+
await elementUpdated(el);
|
|
45
|
+
expect(el.tabIndex).to.equal(-1);
|
|
46
|
+
el.tabIndex = 2;
|
|
47
|
+
await elementUpdated(el);
|
|
48
|
+
expect(el.tabIndex).to.equal(-1);
|
|
49
|
+
el.disabled = false;
|
|
50
|
+
await elementUpdated(el);
|
|
51
|
+
expect(el.tabIndex).to.equal(2);
|
|
52
|
+
});
|
|
53
|
+
it("manages tabIndex before first render", async () => {
|
|
54
|
+
const el = document.createElement("sp-textfield");
|
|
55
|
+
expect(el.focusElement).to.be.null;
|
|
56
|
+
expect(el.tabIndex).to.equal(0);
|
|
57
|
+
el.remove();
|
|
58
|
+
});
|
|
59
|
+
it("loads", async () => {
|
|
60
|
+
const testPlaceholder = "Enter your name";
|
|
61
|
+
const el = await litFixture(
|
|
62
|
+
html`
|
|
63
|
+
<sp-textfield placeholder=${testPlaceholder}></sp-textfield>
|
|
64
|
+
`
|
|
65
|
+
);
|
|
66
|
+
expect(el).to.not.equal(void 0);
|
|
67
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("input") : null;
|
|
68
|
+
expect(input).to.not.be.null;
|
|
69
|
+
const placeholder = input ? input.placeholder : null;
|
|
70
|
+
expect(placeholder).to.equal(testPlaceholder);
|
|
71
|
+
});
|
|
72
|
+
it("multiline", async () => {
|
|
73
|
+
const el = await litFixture(
|
|
74
|
+
html`
|
|
12
75
|
<sp-textfield
|
|
13
76
|
placeholder="Enter your name"
|
|
14
77
|
multiline
|
|
15
78
|
></sp-textfield>
|
|
16
|
-
`
|
|
79
|
+
`
|
|
80
|
+
);
|
|
81
|
+
expect(el).to.not.equal(void 0);
|
|
82
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("textarea") : null;
|
|
83
|
+
expect(input).to.not.be.null;
|
|
84
|
+
});
|
|
85
|
+
it("resizes by default", async () => {
|
|
86
|
+
const el = await litFixture(
|
|
87
|
+
html`
|
|
17
88
|
<sp-textfield
|
|
18
89
|
multiline
|
|
19
90
|
label="No resize control"
|
|
20
91
|
placeholder="No resize control"
|
|
21
92
|
></sp-textfield>
|
|
22
|
-
`
|
|
93
|
+
`
|
|
94
|
+
);
|
|
95
|
+
const startBounds = el.getBoundingClientRect();
|
|
96
|
+
await sendMouse({
|
|
97
|
+
steps: [
|
|
98
|
+
{
|
|
99
|
+
type: "move",
|
|
100
|
+
position: [startBounds.right - 2, startBounds.bottom - 2]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
type: "down"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
type: "move",
|
|
107
|
+
position: [startBounds.right + 50, startBounds.bottom + 50]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
type: "up"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
});
|
|
114
|
+
const endBounds = el.getBoundingClientRect();
|
|
115
|
+
expect(endBounds.width).to.be.greaterThan(startBounds.width);
|
|
116
|
+
expect(endBounds.height).to.be.greaterThan(startBounds.height);
|
|
117
|
+
});
|
|
118
|
+
it("accepts resize styling", async () => {
|
|
119
|
+
const el = await litFixture(
|
|
120
|
+
html`
|
|
23
121
|
<sp-textfield
|
|
24
122
|
multiline
|
|
25
123
|
style="resize: none;"
|
|
26
124
|
label="No resize control"
|
|
27
125
|
placeholder="No resize control"
|
|
28
126
|
></sp-textfield>
|
|
29
|
-
`
|
|
127
|
+
`
|
|
128
|
+
);
|
|
129
|
+
const startBounds = el.getBoundingClientRect();
|
|
130
|
+
await sendMouse({
|
|
131
|
+
steps: [
|
|
132
|
+
{
|
|
133
|
+
type: "move",
|
|
134
|
+
position: [startBounds.right - 2, startBounds.bottom - 2]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
type: "down"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
type: "move",
|
|
141
|
+
position: [startBounds.right + 50, startBounds.bottom + 50]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
type: "up"
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
});
|
|
148
|
+
const endBounds = el.getBoundingClientRect();
|
|
149
|
+
expect(endBounds.width).equals(startBounds.width);
|
|
150
|
+
expect(endBounds.height).equals(startBounds.height);
|
|
151
|
+
});
|
|
152
|
+
it("grows", async () => {
|
|
153
|
+
const el = await litFixture(
|
|
154
|
+
html`
|
|
30
155
|
<sp-textfield
|
|
31
156
|
placeholder="Enter your name"
|
|
32
157
|
multiline
|
|
33
158
|
grows
|
|
34
159
|
></sp-textfield>
|
|
35
|
-
`
|
|
160
|
+
`
|
|
161
|
+
);
|
|
162
|
+
expect(el).to.not.equal(void 0);
|
|
163
|
+
const sizer = el.shadowRoot ? el.shadowRoot.querySelector("#sizer") : null;
|
|
164
|
+
expect(sizer).to.not.be.null;
|
|
165
|
+
});
|
|
166
|
+
it("valid", async () => {
|
|
167
|
+
const el = await litFixture(
|
|
168
|
+
html`
|
|
36
169
|
<sp-textfield
|
|
37
170
|
placeholder="Enter your number"
|
|
38
171
|
pattern="[\\d]+"
|
|
39
172
|
value="123"
|
|
40
173
|
required
|
|
41
174
|
></sp-textfield>
|
|
42
|
-
`
|
|
175
|
+
`
|
|
176
|
+
);
|
|
177
|
+
await elementUpdated(el);
|
|
178
|
+
expect(el).to.not.equal(void 0);
|
|
179
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#valid") : null;
|
|
180
|
+
expect(input).to.not.be.null;
|
|
181
|
+
});
|
|
182
|
+
it("valid - multiline", async () => {
|
|
183
|
+
const el = await litFixture(
|
|
184
|
+
html`
|
|
43
185
|
<sp-textfield
|
|
44
186
|
placeholder="Enter your number"
|
|
45
187
|
pattern="[\\d]+"
|
|
@@ -47,27 +189,63 @@ import{elementUpdated as a,expect as l,html as i,litFixture as n}from"@open-wc/t
|
|
|
47
189
|
required
|
|
48
190
|
multiline
|
|
49
191
|
></sp-textfield>
|
|
50
|
-
`
|
|
192
|
+
`
|
|
193
|
+
);
|
|
194
|
+
await elementUpdated(el);
|
|
195
|
+
expect(el).to.not.equal(void 0);
|
|
196
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#valid") : null;
|
|
197
|
+
expect(input).to.not.be.null;
|
|
198
|
+
});
|
|
199
|
+
it("valid - required", async () => {
|
|
200
|
+
const el = await litFixture(
|
|
201
|
+
html`
|
|
51
202
|
<sp-textfield
|
|
52
203
|
placeholder="Enter your number"
|
|
53
204
|
value="123"
|
|
54
205
|
required
|
|
55
206
|
></sp-textfield>
|
|
56
|
-
`
|
|
207
|
+
`
|
|
208
|
+
);
|
|
209
|
+
await elementUpdated(el);
|
|
210
|
+
expect(el).to.not.equal(void 0);
|
|
211
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#valid") : null;
|
|
212
|
+
expect(input).to.not.be.null;
|
|
213
|
+
});
|
|
214
|
+
it("valid - multiline - required", async () => {
|
|
215
|
+
const el = await litFixture(
|
|
216
|
+
html`
|
|
57
217
|
<sp-textfield
|
|
58
218
|
placeholder="Enter your number"
|
|
59
219
|
value="123"
|
|
60
220
|
required
|
|
61
221
|
multiline
|
|
62
222
|
></sp-textfield>
|
|
63
|
-
`
|
|
223
|
+
`
|
|
224
|
+
);
|
|
225
|
+
await elementUpdated(el);
|
|
226
|
+
expect(el).to.not.equal(void 0);
|
|
227
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#valid") : null;
|
|
228
|
+
expect(input).to.not.be.null;
|
|
229
|
+
});
|
|
230
|
+
it("valid - boundary-type assertions", async () => {
|
|
231
|
+
const el = await litFixture(
|
|
232
|
+
html`
|
|
64
233
|
<sp-textfield
|
|
65
234
|
placeholder="Enter your number"
|
|
66
235
|
pattern="^[\\d]+$"
|
|
67
236
|
value="123"
|
|
68
237
|
required
|
|
69
238
|
></sp-textfield>
|
|
70
|
-
`
|
|
239
|
+
`
|
|
240
|
+
);
|
|
241
|
+
await elementUpdated(el);
|
|
242
|
+
expect(el).to.not.equal(void 0);
|
|
243
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#valid") : null;
|
|
244
|
+
expect(input).to.not.be.null;
|
|
245
|
+
});
|
|
246
|
+
it("valid - multiline - boundary-type assertions", async () => {
|
|
247
|
+
const el = await litFixture(
|
|
248
|
+
html`
|
|
71
249
|
<sp-textfield
|
|
72
250
|
placeholder="Enter your number"
|
|
73
251
|
pattern="^[\\d]+$"
|
|
@@ -75,14 +253,32 @@ import{elementUpdated as a,expect as l,html as i,litFixture as n}from"@open-wc/t
|
|
|
75
253
|
required
|
|
76
254
|
multiline
|
|
77
255
|
></sp-textfield>
|
|
78
|
-
`
|
|
256
|
+
`
|
|
257
|
+
);
|
|
258
|
+
await elementUpdated(el);
|
|
259
|
+
expect(el).to.not.equal(void 0);
|
|
260
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#valid") : null;
|
|
261
|
+
expect(input).to.not.be.null;
|
|
262
|
+
});
|
|
263
|
+
it("valid - unicode", async () => {
|
|
264
|
+
const el = await litFixture(
|
|
265
|
+
html`
|
|
79
266
|
<sp-textfield
|
|
80
267
|
placeholder="Enter your name"
|
|
81
268
|
pattern="\\p{L}{4,8}"
|
|
82
269
|
value="你的名字"
|
|
83
270
|
required
|
|
84
271
|
></sp-textfield>
|
|
85
|
-
`
|
|
272
|
+
`
|
|
273
|
+
);
|
|
274
|
+
await elementUpdated(el);
|
|
275
|
+
expect(el).to.not.equal(void 0);
|
|
276
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#valid") : null;
|
|
277
|
+
expect(input).to.not.be.null;
|
|
278
|
+
});
|
|
279
|
+
it("valid - multiline - unicode", async () => {
|
|
280
|
+
const el = await litFixture(
|
|
281
|
+
html`
|
|
86
282
|
<sp-textfield
|
|
87
283
|
placeholder="Enter your name"
|
|
88
284
|
pattern="\\p{L}{4,8}"
|
|
@@ -90,14 +286,32 @@ import{elementUpdated as a,expect as l,html as i,litFixture as n}from"@open-wc/t
|
|
|
90
286
|
required
|
|
91
287
|
multiline
|
|
92
288
|
></sp-textfield>
|
|
93
|
-
`
|
|
289
|
+
`
|
|
290
|
+
);
|
|
291
|
+
await elementUpdated(el);
|
|
292
|
+
expect(el).to.not.equal(void 0);
|
|
293
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#valid") : null;
|
|
294
|
+
expect(input).to.not.be.null;
|
|
295
|
+
});
|
|
296
|
+
it("invalid", async () => {
|
|
297
|
+
const el = await litFixture(
|
|
298
|
+
html`
|
|
94
299
|
<sp-textfield
|
|
95
300
|
placeholder="Enter your number"
|
|
96
301
|
pattern="[\\d]+"
|
|
97
302
|
value="123 not valid"
|
|
98
303
|
required
|
|
99
304
|
></sp-textfield>
|
|
100
|
-
`
|
|
305
|
+
`
|
|
306
|
+
);
|
|
307
|
+
await elementUpdated(el);
|
|
308
|
+
expect(el).to.not.equal(void 0);
|
|
309
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#invalid") : null;
|
|
310
|
+
expect(input).to.not.be.null;
|
|
311
|
+
});
|
|
312
|
+
it("invalid - multiline", async () => {
|
|
313
|
+
const el = await litFixture(
|
|
314
|
+
html`
|
|
101
315
|
<sp-textfield
|
|
102
316
|
placeholder="Enter your number"
|
|
103
317
|
pattern="[\\d]+"
|
|
@@ -105,27 +319,63 @@ import{elementUpdated as a,expect as l,html as i,litFixture as n}from"@open-wc/t
|
|
|
105
319
|
required
|
|
106
320
|
multiline
|
|
107
321
|
></sp-textfield>
|
|
108
|
-
`
|
|
322
|
+
`
|
|
323
|
+
);
|
|
324
|
+
await elementUpdated(el);
|
|
325
|
+
expect(el).to.not.equal(void 0);
|
|
326
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#invalid") : null;
|
|
327
|
+
expect(input).to.not.be.null;
|
|
328
|
+
});
|
|
329
|
+
it("invalid - required", async () => {
|
|
330
|
+
const el = await litFixture(
|
|
331
|
+
html`
|
|
109
332
|
<sp-textfield
|
|
110
333
|
placeholder="Enter your number"
|
|
111
334
|
value=""
|
|
112
335
|
required
|
|
113
336
|
></sp-textfield>
|
|
114
|
-
`
|
|
337
|
+
`
|
|
338
|
+
);
|
|
339
|
+
await elementUpdated(el);
|
|
340
|
+
expect(el).to.not.equal(void 0);
|
|
341
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#invalid") : null;
|
|
342
|
+
expect(input).to.not.be.null;
|
|
343
|
+
});
|
|
344
|
+
it("invalid - multiline - required", async () => {
|
|
345
|
+
const el = await litFixture(
|
|
346
|
+
html`
|
|
115
347
|
<sp-textfield
|
|
116
348
|
placeholder="Enter your number"
|
|
117
349
|
value=""
|
|
118
350
|
required
|
|
119
351
|
multiline
|
|
120
352
|
></sp-textfield>
|
|
121
|
-
`
|
|
353
|
+
`
|
|
354
|
+
);
|
|
355
|
+
await elementUpdated(el);
|
|
356
|
+
expect(el).to.not.equal(void 0);
|
|
357
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#invalid") : null;
|
|
358
|
+
expect(input).to.not.be.null;
|
|
359
|
+
});
|
|
360
|
+
it("invalid - unicode", async () => {
|
|
361
|
+
const el = await litFixture(
|
|
362
|
+
html`
|
|
122
363
|
<sp-textfield
|
|
123
364
|
placeholder="Enter your number"
|
|
124
365
|
pattern="\\p{N}+"
|
|
125
366
|
value="123 not valid"
|
|
126
367
|
required
|
|
127
368
|
></sp-textfield>
|
|
128
|
-
`
|
|
369
|
+
`
|
|
370
|
+
);
|
|
371
|
+
await elementUpdated(el);
|
|
372
|
+
expect(el).to.not.equal(void 0);
|
|
373
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#invalid") : null;
|
|
374
|
+
expect(input).to.not.be.null;
|
|
375
|
+
});
|
|
376
|
+
it("invalid - multiline - unicode", async () => {
|
|
377
|
+
const el = await litFixture(
|
|
378
|
+
html`
|
|
129
379
|
<sp-textfield
|
|
130
380
|
placeholder="Enter your number"
|
|
131
381
|
pattern="\\p{N}+"
|
|
@@ -133,14 +383,32 @@ import{elementUpdated as a,expect as l,html as i,litFixture as n}from"@open-wc/t
|
|
|
133
383
|
required
|
|
134
384
|
multiline
|
|
135
385
|
></sp-textfield>
|
|
136
|
-
`
|
|
386
|
+
`
|
|
387
|
+
);
|
|
388
|
+
await elementUpdated(el);
|
|
389
|
+
expect(el).to.not.equal(void 0);
|
|
390
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#invalid") : null;
|
|
391
|
+
expect(input).to.not.be.null;
|
|
392
|
+
});
|
|
393
|
+
it("invalid - boundary-type assertions", async () => {
|
|
394
|
+
const el = await litFixture(
|
|
395
|
+
html`
|
|
137
396
|
<sp-textfield
|
|
138
397
|
placeholder="Enter your number"
|
|
139
398
|
pattern="^\\p{N}+$"
|
|
140
399
|
value="123 not valid"
|
|
141
400
|
required
|
|
142
401
|
></sp-textfield>
|
|
143
|
-
`
|
|
402
|
+
`
|
|
403
|
+
);
|
|
404
|
+
await elementUpdated(el);
|
|
405
|
+
expect(el).to.not.equal(void 0);
|
|
406
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#invalid") : null;
|
|
407
|
+
expect(input).to.not.be.null;
|
|
408
|
+
});
|
|
409
|
+
it("invalid - multiline - boundary-type assertions", async () => {
|
|
410
|
+
const el = await litFixture(
|
|
411
|
+
html`
|
|
144
412
|
<sp-textfield
|
|
145
413
|
placeholder="Enter your number"
|
|
146
414
|
pattern="^\\p{N}+$"
|
|
@@ -148,74 +416,357 @@ import{elementUpdated as a,expect as l,html as i,litFixture as n}from"@open-wc/t
|
|
|
148
416
|
required
|
|
149
417
|
multiline
|
|
150
418
|
></sp-textfield>
|
|
151
|
-
`
|
|
419
|
+
`
|
|
420
|
+
);
|
|
421
|
+
await elementUpdated(el);
|
|
422
|
+
expect(el).to.not.equal(void 0);
|
|
423
|
+
const input = el.shadowRoot ? el.shadowRoot.querySelector("#invalid") : null;
|
|
424
|
+
expect(input).to.not.be.null;
|
|
425
|
+
});
|
|
426
|
+
it("receives focus", async () => {
|
|
427
|
+
let activeElement = null;
|
|
428
|
+
const onFocusIn = (event) => {
|
|
429
|
+
const path = event.composedPath();
|
|
430
|
+
activeElement = path[0];
|
|
431
|
+
};
|
|
432
|
+
document.addEventListener("focusin", onFocusIn);
|
|
433
|
+
const el = await litFixture(
|
|
434
|
+
html`
|
|
152
435
|
<sp-textfield placeholder="Enter your name"></sp-textfield>
|
|
153
|
-
`
|
|
436
|
+
`
|
|
437
|
+
);
|
|
438
|
+
await elementUpdated(el);
|
|
439
|
+
el.focus();
|
|
440
|
+
await elementUpdated(el);
|
|
441
|
+
expect(activeElement === el.focusElement).to.be.true;
|
|
442
|
+
document.removeEventListener("focusin", onFocusIn);
|
|
443
|
+
});
|
|
444
|
+
it("does not receive focus when disabled", async () => {
|
|
445
|
+
let activeElement = null;
|
|
446
|
+
const onFocusIn = (event) => {
|
|
447
|
+
const path = event.composedPath();
|
|
448
|
+
activeElement = path[0];
|
|
449
|
+
};
|
|
450
|
+
document.addEventListener("focusin", onFocusIn);
|
|
451
|
+
const el = await litFixture(
|
|
452
|
+
html`
|
|
154
453
|
<sp-textfield
|
|
155
454
|
disabled
|
|
156
455
|
placeholder="Enter your name"
|
|
157
456
|
></sp-textfield>
|
|
158
|
-
`
|
|
457
|
+
`
|
|
458
|
+
);
|
|
459
|
+
await elementUpdated(el);
|
|
460
|
+
el.focus();
|
|
461
|
+
await elementUpdated(el);
|
|
462
|
+
expect(activeElement === el.focusElement).to.be.false;
|
|
463
|
+
expect(document.activeElement === el).to.be.false;
|
|
464
|
+
document.removeEventListener("focusin", onFocusIn);
|
|
465
|
+
el.click();
|
|
466
|
+
await elementUpdated(el);
|
|
467
|
+
expect(activeElement === el.focusElement).to.be.false;
|
|
468
|
+
expect(document.activeElement === el).to.be.false;
|
|
469
|
+
document.removeEventListener("focusin", onFocusIn);
|
|
470
|
+
});
|
|
471
|
+
it("accepts input", async () => {
|
|
472
|
+
const testValue = "Test Name";
|
|
473
|
+
const el = await litFixture(
|
|
474
|
+
html`
|
|
159
475
|
<sp-textfield placeholder="Enter your name"></sp-textfield>
|
|
160
|
-
`
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
476
|
+
`
|
|
477
|
+
);
|
|
478
|
+
await elementUpdated(el);
|
|
479
|
+
el.focusElement.value = testValue;
|
|
480
|
+
el.focusElement.dispatchEvent(new Event("input"));
|
|
481
|
+
expect(el.value).to.equal(testValue);
|
|
482
|
+
});
|
|
483
|
+
it("selects", async () => {
|
|
484
|
+
const testValue = "Test Name";
|
|
485
|
+
const el = await litFixture(
|
|
486
|
+
html`
|
|
487
|
+
<sp-textfield value=${testValue}></sp-textfield>
|
|
488
|
+
`
|
|
489
|
+
);
|
|
490
|
+
await elementUpdated(el);
|
|
491
|
+
expect(el.value).to.equal(testValue);
|
|
492
|
+
el.focus();
|
|
493
|
+
el.select();
|
|
494
|
+
await sendKeys({ press: "Backspace" });
|
|
495
|
+
expect(el.value).to.equal("");
|
|
496
|
+
});
|
|
497
|
+
it("setSelectionRange", async () => {
|
|
498
|
+
const testValue = "Test Name";
|
|
499
|
+
const el = await litFixture(
|
|
500
|
+
html`
|
|
501
|
+
<sp-textfield value=${testValue}></sp-textfield>
|
|
502
|
+
`
|
|
503
|
+
);
|
|
504
|
+
await elementUpdated(el);
|
|
505
|
+
expect(el.value).to.equal(testValue);
|
|
506
|
+
el.focus();
|
|
507
|
+
el.setSelectionRange(0, "Test ".length);
|
|
508
|
+
await sendKeys({ press: "Backspace" });
|
|
509
|
+
expect(el.value).to.equal("Name");
|
|
510
|
+
});
|
|
511
|
+
it("accepts maxlength", async () => {
|
|
512
|
+
const el = await litFixture(
|
|
513
|
+
html`
|
|
165
514
|
<sp-textfield
|
|
166
515
|
placeholder="Enter your name"
|
|
167
516
|
maxlength="3"
|
|
168
517
|
minlength="2"
|
|
169
518
|
required
|
|
170
519
|
></sp-textfield>
|
|
171
|
-
`
|
|
520
|
+
`
|
|
521
|
+
);
|
|
522
|
+
await elementUpdated(el);
|
|
523
|
+
el.focus();
|
|
524
|
+
await sendKeys({
|
|
525
|
+
type: "a"
|
|
526
|
+
});
|
|
527
|
+
await elementUpdated(el);
|
|
528
|
+
expect(el.value).to.equal("a");
|
|
529
|
+
expect(el.checkValidity()).to.be.false;
|
|
530
|
+
await sendKeys({
|
|
531
|
+
type: "b"
|
|
532
|
+
});
|
|
533
|
+
await elementUpdated(el);
|
|
534
|
+
expect(el.value).to.equal("ab");
|
|
535
|
+
expect(el.checkValidity());
|
|
536
|
+
await sendKeys({
|
|
537
|
+
type: "c"
|
|
538
|
+
});
|
|
539
|
+
await elementUpdated(el);
|
|
540
|
+
expect(el.value).to.equal("abc");
|
|
541
|
+
expect(el.checkValidity());
|
|
542
|
+
await sendKeys({
|
|
543
|
+
type: "d"
|
|
544
|
+
});
|
|
545
|
+
await elementUpdated(el);
|
|
546
|
+
expect(el.value).to.equal("abc");
|
|
547
|
+
expect(el.checkValidity());
|
|
548
|
+
await sendKeys({
|
|
549
|
+
press: "Backspace"
|
|
550
|
+
});
|
|
551
|
+
await elementUpdated(el);
|
|
552
|
+
expect(el.value).to.equal("ab");
|
|
553
|
+
expect(el.checkValidity());
|
|
554
|
+
await sendKeys({
|
|
555
|
+
press: "Backspace"
|
|
556
|
+
});
|
|
557
|
+
await elementUpdated(el);
|
|
558
|
+
expect(el.value).to.equal("a");
|
|
559
|
+
expect(el.checkValidity()).to.be.false;
|
|
560
|
+
});
|
|
561
|
+
it("dispatches a `change` event", async () => {
|
|
562
|
+
const testValue = "Test Name";
|
|
563
|
+
let eventSource = null;
|
|
564
|
+
const onChange = (event) => {
|
|
565
|
+
eventSource = event.composedPath()[0];
|
|
566
|
+
};
|
|
567
|
+
const el = await litFixture(
|
|
568
|
+
html`
|
|
172
569
|
<sp-textfield
|
|
173
570
|
placeholder="Enter your name"
|
|
174
|
-
@change=${
|
|
571
|
+
@change=${onChange}
|
|
175
572
|
></sp-textfield>
|
|
176
|
-
`
|
|
573
|
+
`
|
|
574
|
+
);
|
|
575
|
+
await elementUpdated(el);
|
|
576
|
+
el.focusElement.value = testValue;
|
|
577
|
+
el.focusElement.dispatchEvent(new Event("input"));
|
|
578
|
+
el.focusElement.dispatchEvent(new Event("change"));
|
|
579
|
+
expect(el.value).to.equal(testValue);
|
|
580
|
+
const testSource = eventSource;
|
|
581
|
+
expect(testSource).to.equal(el);
|
|
582
|
+
});
|
|
583
|
+
it("passes through `autocomplete` attribute", async () => {
|
|
584
|
+
let el = await litFixture(
|
|
585
|
+
html`
|
|
177
586
|
<sp-textfield autocomplete="off"></sp-textfield>
|
|
178
|
-
`
|
|
587
|
+
`
|
|
588
|
+
);
|
|
589
|
+
await elementUpdated(el);
|
|
590
|
+
let input = el.shadowRoot ? el.shadowRoot.querySelector("input") : null;
|
|
591
|
+
expect(input).to.exist;
|
|
592
|
+
if (input) {
|
|
593
|
+
expect(input.getAttribute("autocomplete")).to.equal("off");
|
|
594
|
+
}
|
|
595
|
+
el = await litFixture(
|
|
596
|
+
html`
|
|
179
597
|
<sp-textfield></sp-textfield>
|
|
180
|
-
`
|
|
598
|
+
`
|
|
599
|
+
);
|
|
600
|
+
await elementUpdated(el);
|
|
601
|
+
input = el.shadowRoot ? el.shadowRoot.querySelector("input") : null;
|
|
602
|
+
expect(input).to.exist;
|
|
603
|
+
if (input) {
|
|
604
|
+
expect(input.getAttribute("autocomplete")).to.not.exist;
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
it("tests on `required` changes", async () => {
|
|
608
|
+
const el = await litFixture(
|
|
609
|
+
html`
|
|
181
610
|
<sp-textfield value=""></sp-textfield>
|
|
182
|
-
`
|
|
611
|
+
`
|
|
612
|
+
);
|
|
613
|
+
await elementUpdated(el);
|
|
614
|
+
expect(el.invalid).to.be.false;
|
|
615
|
+
el.required = true;
|
|
616
|
+
await elementUpdated(el);
|
|
617
|
+
expect(el.invalid).to.be.true;
|
|
618
|
+
});
|
|
619
|
+
it("manages `allowed-keys`", async () => {
|
|
620
|
+
const el = await litFixture(
|
|
621
|
+
html`
|
|
183
622
|
<sp-textfield allowed-keys="asdf"></sp-textfield>
|
|
184
|
-
`
|
|
623
|
+
`
|
|
624
|
+
);
|
|
625
|
+
await elementUpdated(el);
|
|
626
|
+
expect(el.value).to.equal("");
|
|
627
|
+
const inputElement = el.focusElement;
|
|
628
|
+
el.focusElement.value = "asdf";
|
|
629
|
+
inputElement.dispatchEvent(new InputEvent("input"));
|
|
630
|
+
await elementUpdated(el);
|
|
631
|
+
expect(el.value).to.equal("asdf");
|
|
632
|
+
inputElement.value = `asdff`;
|
|
633
|
+
inputElement.setSelectionRange(1, 1);
|
|
634
|
+
inputElement.dispatchEvent(new InputEvent("input"));
|
|
635
|
+
await elementUpdated(el);
|
|
636
|
+
expect(el.value).to.equal("asdff");
|
|
637
|
+
expect(inputElement.selectionStart).to.equal(1);
|
|
638
|
+
inputElement.value = `asdoff`;
|
|
639
|
+
inputElement.setSelectionRange(4, 4);
|
|
640
|
+
inputElement.dispatchEvent(new InputEvent("input"));
|
|
641
|
+
await elementUpdated(el);
|
|
642
|
+
expect(el.value).to.equal("asdff");
|
|
643
|
+
expect(inputElement.selectionStart).to.equal(3);
|
|
644
|
+
});
|
|
645
|
+
describe("type attribute", () => {
|
|
646
|
+
it("assigns valid attributes to the property", async () => {
|
|
647
|
+
const types = [
|
|
648
|
+
"text",
|
|
649
|
+
"url",
|
|
650
|
+
"tel",
|
|
651
|
+
"email",
|
|
652
|
+
"password"
|
|
653
|
+
];
|
|
654
|
+
for await (const t of types) {
|
|
655
|
+
const el = await litFixture(
|
|
656
|
+
html`
|
|
185
657
|
<sp-textfield type=${t}></sp-textfield>
|
|
186
|
-
`
|
|
658
|
+
`
|
|
659
|
+
);
|
|
660
|
+
expect(el.type).equals(t);
|
|
661
|
+
el.setAttribute("type", "url");
|
|
662
|
+
expect(el.type).equals("url");
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
it('represents invalid and missing attributes as "text"', async () => {
|
|
666
|
+
const el1 = await litFixture(
|
|
667
|
+
html`
|
|
187
668
|
<sp-textfield></sp-textfield>
|
|
188
|
-
`
|
|
669
|
+
`
|
|
670
|
+
);
|
|
671
|
+
const el2 = await litFixture(
|
|
672
|
+
html`
|
|
189
673
|
<sp-textfield type="time"></sp-textfield>
|
|
190
|
-
`
|
|
674
|
+
`
|
|
675
|
+
);
|
|
676
|
+
expect(el1.type).equals("text");
|
|
677
|
+
expect(el2.type).equals("text");
|
|
678
|
+
el1.setAttribute("type", "submit");
|
|
679
|
+
expect(el1.type).equals("text");
|
|
680
|
+
});
|
|
681
|
+
it("reflects valid property assignments", async () => {
|
|
682
|
+
const el = await litFixture(
|
|
683
|
+
html`
|
|
191
684
|
<sp-textfield type="url"></sp-textfield>
|
|
192
|
-
`
|
|
685
|
+
`
|
|
686
|
+
);
|
|
687
|
+
el.type = "email";
|
|
688
|
+
await elementUpdated(el);
|
|
689
|
+
expect(el.getAttribute("type")).equals("email");
|
|
690
|
+
expect(el.type).equals("email");
|
|
691
|
+
});
|
|
692
|
+
it('reflects invalid assignments but sets state to "text"', async () => {
|
|
693
|
+
const el = await litFixture(
|
|
694
|
+
html`
|
|
193
695
|
<sp-textfield type="url"></sp-textfield>
|
|
194
|
-
`
|
|
195
|
-
|
|
196
|
-
|
|
696
|
+
`
|
|
697
|
+
);
|
|
698
|
+
el.type = "range";
|
|
699
|
+
await elementUpdated(el);
|
|
700
|
+
expect(el.getAttribute("type")).equals("range");
|
|
701
|
+
expect(el.type).equals("text");
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
describe("help text", () => {
|
|
705
|
+
const name = "This is a textfield";
|
|
706
|
+
const description = "This text helps you fill it out";
|
|
707
|
+
const descriptionNegative = "This text helps you when invalid";
|
|
708
|
+
it('accepts help text in `slot="help-text"`', async () => {
|
|
709
|
+
const el = await litFixture(html`
|
|
710
|
+
<sp-textfield label=${name}>
|
|
711
|
+
<sp-help-text slot="help-text">${description}</sp-help-text>
|
|
197
712
|
</sp-textfield>
|
|
198
|
-
`);
|
|
199
|
-
|
|
713
|
+
`);
|
|
714
|
+
await elementUpdated(el);
|
|
715
|
+
await findDescribedNode(name, description);
|
|
716
|
+
});
|
|
717
|
+
it('accepts help text in `slot="help-text"` w/ own ID', async () => {
|
|
718
|
+
const el = await litFixture(html`
|
|
719
|
+
<sp-textfield label=${name}>
|
|
200
720
|
<sp-help-text slot="help-text" id="help-text-id-1">
|
|
201
|
-
${
|
|
721
|
+
${description}
|
|
202
722
|
</sp-help-text>
|
|
203
723
|
</sp-textfield>
|
|
204
|
-
`);
|
|
205
|
-
|
|
206
|
-
|
|
724
|
+
`);
|
|
725
|
+
await elementUpdated(el);
|
|
726
|
+
await findDescribedNode(name, description);
|
|
727
|
+
});
|
|
728
|
+
it("manages neutral/negative help text pairs", async () => {
|
|
729
|
+
const el = await litFixture(html`
|
|
730
|
+
<sp-textfield label=${name}>
|
|
731
|
+
<sp-help-text slot="help-text">${description}</sp-help-text>
|
|
207
732
|
<sp-help-text slot="negative-help-text">
|
|
208
|
-
${
|
|
733
|
+
${descriptionNegative}
|
|
209
734
|
</sp-help-text>
|
|
210
735
|
</sp-textfield>
|
|
211
|
-
`)
|
|
212
|
-
|
|
736
|
+
`);
|
|
737
|
+
const negativeHelpText = el.querySelector(
|
|
738
|
+
'[slot="negative-help-text"]'
|
|
739
|
+
);
|
|
740
|
+
await elementUpdated(el);
|
|
741
|
+
expect(negativeHelpText.variant).to.equal("neutral");
|
|
742
|
+
await findDescribedNode(name, description);
|
|
743
|
+
el.invalid = true;
|
|
744
|
+
await elementUpdated(el);
|
|
745
|
+
expect(negativeHelpText.variant).to.equal("negative");
|
|
746
|
+
await findDescribedNode(name, descriptionNegative);
|
|
747
|
+
});
|
|
748
|
+
it("manages neutral/negative help text pairs w/ own IDs", async () => {
|
|
749
|
+
const el = await litFixture(html`
|
|
750
|
+
<sp-textfield label=${name}>
|
|
213
751
|
<sp-help-text slot="help-text" id="help-text-id-2">
|
|
214
|
-
${
|
|
752
|
+
${description}
|
|
215
753
|
</sp-help-text>
|
|
216
754
|
<sp-help-text slot="negative-help-text" id="help-text-id-3">
|
|
217
|
-
${
|
|
755
|
+
${descriptionNegative}
|
|
218
756
|
</sp-help-text>
|
|
219
757
|
</sp-textfield>
|
|
220
|
-
`)
|
|
758
|
+
`);
|
|
759
|
+
const negativeHelpText = el.querySelector(
|
|
760
|
+
'[slot="negative-help-text"]'
|
|
761
|
+
);
|
|
762
|
+
await elementUpdated(el);
|
|
763
|
+
expect(negativeHelpText.variant).to.equal("neutral");
|
|
764
|
+
await findDescribedNode(name, description);
|
|
765
|
+
el.invalid = true;
|
|
766
|
+
await elementUpdated(el);
|
|
767
|
+
expect(negativeHelpText.variant).to.equal("negative");
|
|
768
|
+
await findDescribedNode(name, descriptionNegative);
|
|
769
|
+
});
|
|
770
|
+
});
|
|
771
|
+
});
|
|
221
772
|
//# sourceMappingURL=textfield.test.js.map
|