@vialiq/web-components 0.9.0 → 0.10.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/base/validity-mixin.d.ts +41 -190
- package/base/validity-mixin.d.ts.map +1 -1
- package/checkbox/vi-checkbox.d.ts +1 -3
- package/checkbox/vi-checkbox.d.ts.map +1 -1
- package/checkbox/vi-checkbox.js +2 -4
- package/index.d.ts +3 -0
- package/index.js +1490 -67
- package/input/vi-input.d.ts +1 -3
- package/input/vi-input.d.ts.map +1 -1
- package/input/vi-input.js +2 -4
- package/package.json +2 -2
- package/radio/vi-radio-group.d.ts +1 -3
- package/radio/vi-radio-group.d.ts.map +1 -1
- package/radio/vi-radio-group.js +2 -4
- package/validity-mixin-H4aOFJEr.js +635 -0
- package/validity-mixin-BjmXwgWk.js +0 -216
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
import { property } from 'lit/decorators.js';
|
|
2
|
+
|
|
3
|
+
function applyDecs2203RFactory() {
|
|
4
|
+
function createAddInitializerMethod(initializers, decoratorFinishedRef) {
|
|
5
|
+
return function addInitializer(initializer) {
|
|
6
|
+
assertNotFinished(decoratorFinishedRef, "addInitializer");
|
|
7
|
+
assertCallable(initializer, "An initializer");
|
|
8
|
+
initializers.push(initializer);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value) {
|
|
12
|
+
var kindStr;
|
|
13
|
+
switch(kind){
|
|
14
|
+
case 1:
|
|
15
|
+
kindStr = "accessor";
|
|
16
|
+
break;
|
|
17
|
+
case 2:
|
|
18
|
+
kindStr = "method";
|
|
19
|
+
break;
|
|
20
|
+
case 3:
|
|
21
|
+
kindStr = "getter";
|
|
22
|
+
break;
|
|
23
|
+
case 4:
|
|
24
|
+
kindStr = "setter";
|
|
25
|
+
break;
|
|
26
|
+
default:
|
|
27
|
+
kindStr = "field";
|
|
28
|
+
}
|
|
29
|
+
var ctx = {
|
|
30
|
+
kind: kindStr,
|
|
31
|
+
name: isPrivate ? "#" + name : name,
|
|
32
|
+
static: isStatic,
|
|
33
|
+
private: isPrivate,
|
|
34
|
+
metadata: metadata
|
|
35
|
+
};
|
|
36
|
+
var decoratorFinishedRef = {
|
|
37
|
+
v: false
|
|
38
|
+
};
|
|
39
|
+
ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef);
|
|
40
|
+
var get, set;
|
|
41
|
+
if (kind === 0) {
|
|
42
|
+
if (isPrivate) {
|
|
43
|
+
get = desc.get;
|
|
44
|
+
set = desc.set;
|
|
45
|
+
} else {
|
|
46
|
+
get = function() {
|
|
47
|
+
return this[name];
|
|
48
|
+
};
|
|
49
|
+
set = function(v) {
|
|
50
|
+
this[name] = v;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
} else if (kind === 2) {
|
|
54
|
+
get = function() {
|
|
55
|
+
return desc.value;
|
|
56
|
+
};
|
|
57
|
+
} else {
|
|
58
|
+
if (kind === 1 || kind === 3) {
|
|
59
|
+
get = function() {
|
|
60
|
+
return desc.get.call(this);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (kind === 1 || kind === 4) {
|
|
64
|
+
set = function(v) {
|
|
65
|
+
desc.set.call(this, v);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
ctx.access = get && set ? {
|
|
70
|
+
get: get,
|
|
71
|
+
set: set
|
|
72
|
+
} : get ? {
|
|
73
|
+
get: get
|
|
74
|
+
} : {
|
|
75
|
+
set: set
|
|
76
|
+
};
|
|
77
|
+
try {
|
|
78
|
+
return dec(value, ctx);
|
|
79
|
+
} finally{
|
|
80
|
+
decoratorFinishedRef.v = true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function assertNotFinished(decoratorFinishedRef, fnName) {
|
|
84
|
+
if (decoratorFinishedRef.v) {
|
|
85
|
+
throw new Error("attempted to call " + fnName + " after decoration was finished");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function assertCallable(fn, hint) {
|
|
89
|
+
if (typeof fn !== "function") {
|
|
90
|
+
throw new TypeError(hint + " must be a function");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function assertValidReturnValue(kind, value) {
|
|
94
|
+
var type = typeof value;
|
|
95
|
+
if (kind === 1) {
|
|
96
|
+
if (type !== "object" || value === null) {
|
|
97
|
+
throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
|
|
98
|
+
}
|
|
99
|
+
if (value.get !== undefined) {
|
|
100
|
+
assertCallable(value.get, "accessor.get");
|
|
101
|
+
}
|
|
102
|
+
if (value.set !== undefined) {
|
|
103
|
+
assertCallable(value.set, "accessor.set");
|
|
104
|
+
}
|
|
105
|
+
if (value.init !== undefined) {
|
|
106
|
+
assertCallable(value.init, "accessor.init");
|
|
107
|
+
}
|
|
108
|
+
} else if (type !== "function") {
|
|
109
|
+
var hint;
|
|
110
|
+
if (kind === 0) {
|
|
111
|
+
hint = "field";
|
|
112
|
+
} else if (kind === 10) {
|
|
113
|
+
hint = "class";
|
|
114
|
+
} else {
|
|
115
|
+
hint = "method";
|
|
116
|
+
}
|
|
117
|
+
throw new TypeError(hint + " decorators must return a function or void 0");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata) {
|
|
121
|
+
var decs = decInfo[0];
|
|
122
|
+
var desc, init, value;
|
|
123
|
+
if (isPrivate) {
|
|
124
|
+
if (kind === 0 || kind === 1) {
|
|
125
|
+
desc = {
|
|
126
|
+
get: decInfo[3],
|
|
127
|
+
set: decInfo[4]
|
|
128
|
+
};
|
|
129
|
+
} else if (kind === 3) {
|
|
130
|
+
desc = {
|
|
131
|
+
get: decInfo[3]
|
|
132
|
+
};
|
|
133
|
+
} else if (kind === 4) {
|
|
134
|
+
desc = {
|
|
135
|
+
set: decInfo[3]
|
|
136
|
+
};
|
|
137
|
+
} else {
|
|
138
|
+
desc = {
|
|
139
|
+
value: decInfo[3]
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
} else if (kind !== 0) {
|
|
143
|
+
desc = Object.getOwnPropertyDescriptor(base, name);
|
|
144
|
+
}
|
|
145
|
+
if (kind === 1) {
|
|
146
|
+
value = {
|
|
147
|
+
get: desc.get,
|
|
148
|
+
set: desc.set
|
|
149
|
+
};
|
|
150
|
+
} else if (kind === 2) {
|
|
151
|
+
value = desc.value;
|
|
152
|
+
} else if (kind === 3) {
|
|
153
|
+
value = desc.get;
|
|
154
|
+
} else if (kind === 4) {
|
|
155
|
+
value = desc.set;
|
|
156
|
+
}
|
|
157
|
+
var newValue, get, set;
|
|
158
|
+
if (typeof decs === "function") {
|
|
159
|
+
newValue = memberDec(decs, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
160
|
+
if (newValue !== void 0) {
|
|
161
|
+
assertValidReturnValue(kind, newValue);
|
|
162
|
+
if (kind === 0) {
|
|
163
|
+
init = newValue;
|
|
164
|
+
} else if (kind === 1) {
|
|
165
|
+
init = newValue.init;
|
|
166
|
+
get = newValue.get || value.get;
|
|
167
|
+
set = newValue.set || value.set;
|
|
168
|
+
value = {
|
|
169
|
+
get: get,
|
|
170
|
+
set: set
|
|
171
|
+
};
|
|
172
|
+
} else {
|
|
173
|
+
value = newValue;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
} else {
|
|
177
|
+
for(var i = decs.length - 1; i >= 0; i--){
|
|
178
|
+
var dec = decs[i];
|
|
179
|
+
newValue = memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
180
|
+
if (newValue !== void 0) {
|
|
181
|
+
assertValidReturnValue(kind, newValue);
|
|
182
|
+
var newInit;
|
|
183
|
+
if (kind === 0) {
|
|
184
|
+
newInit = newValue;
|
|
185
|
+
} else if (kind === 1) {
|
|
186
|
+
newInit = newValue.init;
|
|
187
|
+
get = newValue.get || value.get;
|
|
188
|
+
set = newValue.set || value.set;
|
|
189
|
+
value = {
|
|
190
|
+
get: get,
|
|
191
|
+
set: set
|
|
192
|
+
};
|
|
193
|
+
} else {
|
|
194
|
+
value = newValue;
|
|
195
|
+
}
|
|
196
|
+
if (newInit !== void 0) {
|
|
197
|
+
if (init === void 0) {
|
|
198
|
+
init = newInit;
|
|
199
|
+
} else if (typeof init === "function") {
|
|
200
|
+
init = [
|
|
201
|
+
init,
|
|
202
|
+
newInit
|
|
203
|
+
];
|
|
204
|
+
} else {
|
|
205
|
+
init.push(newInit);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (kind === 0 || kind === 1) {
|
|
212
|
+
if (init === void 0) {
|
|
213
|
+
init = function(instance, init) {
|
|
214
|
+
return init;
|
|
215
|
+
};
|
|
216
|
+
} else if (typeof init !== "function") {
|
|
217
|
+
var ownInitializers = init;
|
|
218
|
+
init = function(instance, init) {
|
|
219
|
+
var value = init;
|
|
220
|
+
for(var i = 0; i < ownInitializers.length; i++){
|
|
221
|
+
value = ownInitializers[i].call(instance, value);
|
|
222
|
+
}
|
|
223
|
+
return value;
|
|
224
|
+
};
|
|
225
|
+
} else {
|
|
226
|
+
var originalInitializer = init;
|
|
227
|
+
init = function(instance, init) {
|
|
228
|
+
return originalInitializer.call(instance, init);
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
ret.push(init);
|
|
232
|
+
}
|
|
233
|
+
if (kind !== 0) {
|
|
234
|
+
if (kind === 1) {
|
|
235
|
+
desc.get = value.get;
|
|
236
|
+
desc.set = value.set;
|
|
237
|
+
} else if (kind === 2) {
|
|
238
|
+
desc.value = value;
|
|
239
|
+
} else if (kind === 3) {
|
|
240
|
+
desc.get = value;
|
|
241
|
+
} else if (kind === 4) {
|
|
242
|
+
desc.set = value;
|
|
243
|
+
}
|
|
244
|
+
if (isPrivate) {
|
|
245
|
+
if (kind === 1) {
|
|
246
|
+
ret.push(function(instance, args) {
|
|
247
|
+
return value.get.call(instance, args);
|
|
248
|
+
});
|
|
249
|
+
ret.push(function(instance, args) {
|
|
250
|
+
return value.set.call(instance, args);
|
|
251
|
+
});
|
|
252
|
+
} else if (kind === 2) {
|
|
253
|
+
ret.push(value);
|
|
254
|
+
} else {
|
|
255
|
+
ret.push(function(instance, args) {
|
|
256
|
+
return value.call(instance, args);
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
Object.defineProperty(base, name, desc);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function applyMemberDecs(Class, decInfos, metadata) {
|
|
265
|
+
var ret = [];
|
|
266
|
+
var protoInitializers;
|
|
267
|
+
var staticInitializers;
|
|
268
|
+
var existingProtoNonFields = new Map();
|
|
269
|
+
var existingStaticNonFields = new Map();
|
|
270
|
+
for(var i = 0; i < decInfos.length; i++){
|
|
271
|
+
var decInfo = decInfos[i];
|
|
272
|
+
if (!Array.isArray(decInfo)) continue;
|
|
273
|
+
var kind = decInfo[1];
|
|
274
|
+
var name = decInfo[2];
|
|
275
|
+
var isPrivate = decInfo.length > 3;
|
|
276
|
+
var isStatic = kind >= 5;
|
|
277
|
+
var base;
|
|
278
|
+
var initializers;
|
|
279
|
+
if (isStatic) {
|
|
280
|
+
base = Class;
|
|
281
|
+
kind = kind - 5;
|
|
282
|
+
staticInitializers = staticInitializers || [];
|
|
283
|
+
initializers = staticInitializers;
|
|
284
|
+
} else {
|
|
285
|
+
base = Class.prototype;
|
|
286
|
+
protoInitializers = protoInitializers || [];
|
|
287
|
+
initializers = protoInitializers;
|
|
288
|
+
}
|
|
289
|
+
if (kind !== 0 && !isPrivate) {
|
|
290
|
+
var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields;
|
|
291
|
+
var existingKind = existingNonFields.get(name) || 0;
|
|
292
|
+
if (existingKind === true || existingKind === 3 && kind !== 4 || existingKind === 4 && kind !== 3) {
|
|
293
|
+
throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
|
|
294
|
+
} else if (!existingKind && kind > 2) {
|
|
295
|
+
existingNonFields.set(name, kind);
|
|
296
|
+
} else {
|
|
297
|
+
existingNonFields.set(name, true);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata);
|
|
301
|
+
}
|
|
302
|
+
pushInitializers(ret, protoInitializers);
|
|
303
|
+
pushInitializers(ret, staticInitializers);
|
|
304
|
+
return ret;
|
|
305
|
+
}
|
|
306
|
+
function pushInitializers(ret, initializers) {
|
|
307
|
+
if (initializers) {
|
|
308
|
+
ret.push(function(instance) {
|
|
309
|
+
for(var i = 0; i < initializers.length; i++){
|
|
310
|
+
initializers[i].call(instance);
|
|
311
|
+
}
|
|
312
|
+
return instance;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function applyClassDecs(targetClass, classDecs, metadata) {
|
|
317
|
+
if (classDecs.length > 0) {
|
|
318
|
+
var initializers = [];
|
|
319
|
+
var newClass = targetClass;
|
|
320
|
+
var name = targetClass.name;
|
|
321
|
+
for(var i = classDecs.length - 1; i >= 0; i--){
|
|
322
|
+
var decoratorFinishedRef = {
|
|
323
|
+
v: false
|
|
324
|
+
};
|
|
325
|
+
try {
|
|
326
|
+
var nextNewClass = classDecs[i](newClass, {
|
|
327
|
+
kind: "class",
|
|
328
|
+
name: name,
|
|
329
|
+
addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef),
|
|
330
|
+
metadata
|
|
331
|
+
});
|
|
332
|
+
} finally{
|
|
333
|
+
decoratorFinishedRef.v = true;
|
|
334
|
+
}
|
|
335
|
+
if (nextNewClass !== undefined) {
|
|
336
|
+
assertValidReturnValue(10, nextNewClass);
|
|
337
|
+
newClass = nextNewClass;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return [
|
|
341
|
+
defineMetadata(newClass, metadata),
|
|
342
|
+
function() {
|
|
343
|
+
for(var i = 0; i < initializers.length; i++){
|
|
344
|
+
initializers[i].call(newClass);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
];
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function defineMetadata(Class, metadata) {
|
|
351
|
+
return Object.defineProperty(Class, Symbol.metadata || Symbol.for("Symbol.metadata"), {
|
|
352
|
+
configurable: true,
|
|
353
|
+
enumerable: true,
|
|
354
|
+
value: metadata
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
return function applyDecs2203R(targetClass, memberDecs, classDecs, parentClass) {
|
|
358
|
+
if (parentClass !== void 0) {
|
|
359
|
+
var parentMetadata = parentClass[Symbol.metadata || Symbol.for("Symbol.metadata")];
|
|
360
|
+
}
|
|
361
|
+
var metadata = Object.create(parentMetadata === void 0 ? null : parentMetadata);
|
|
362
|
+
var e = applyMemberDecs(targetClass, memberDecs, metadata);
|
|
363
|
+
if (!classDecs.length) defineMetadata(targetClass, metadata);
|
|
364
|
+
return {
|
|
365
|
+
e: e,
|
|
366
|
+
get c () {
|
|
367
|
+
return applyClassDecs(targetClass, classDecs, metadata);
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
373
|
+
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* ValidityMixin
|
|
377
|
+
*
|
|
378
|
+
* Adds the full WHATWG Constraint Validation API and form-associated lifecycle
|
|
379
|
+
* to any Lit element. Consumers only need to:
|
|
380
|
+
*
|
|
381
|
+
* 1. Override `_testValidity()` to return component-specific validity flags.
|
|
382
|
+
* 2. Declare `value`, `name`, and `disabled` as `@property`.
|
|
383
|
+
* 3. Call `_internals.setFormValue()` in their `updated()` lifecycle.
|
|
384
|
+
*
|
|
385
|
+
* The mixin owns: `static formAssociated`, `_internals`, `status`, `required`,
|
|
386
|
+
* `validityMessage`, and all form lifecycle callbacks.
|
|
387
|
+
*/ function ValidityMixin(Base) {
|
|
388
|
+
var _dec, _dec1, _dec2, // ── Shared validation properties ─────────────────────────────────────────
|
|
389
|
+
// These are the "contract" properties that ValidityMixin manages.
|
|
390
|
+
// Consumers no longer need to declare these themselves.
|
|
391
|
+
_init_status, _init_required, _init_validityMessage, _initProto;
|
|
392
|
+
_dec = property({
|
|
393
|
+
reflect: true
|
|
394
|
+
}), _dec1 = property({
|
|
395
|
+
type: Boolean,
|
|
396
|
+
reflect: true
|
|
397
|
+
}), _dec2 = property({
|
|
398
|
+
attribute: 'validity-message'
|
|
399
|
+
});
|
|
400
|
+
class ValidityMixinClass extends Base {
|
|
401
|
+
static{
|
|
402
|
+
({ e: [_init_status, _init_required, _init_validityMessage, _initProto] } = _apply_decs_2203_r(this, [
|
|
403
|
+
[
|
|
404
|
+
_dec,
|
|
405
|
+
1,
|
|
406
|
+
"status"
|
|
407
|
+
],
|
|
408
|
+
[
|
|
409
|
+
_dec1,
|
|
410
|
+
1,
|
|
411
|
+
"required"
|
|
412
|
+
],
|
|
413
|
+
[
|
|
414
|
+
_dec2,
|
|
415
|
+
1,
|
|
416
|
+
"validityMessage"
|
|
417
|
+
]
|
|
418
|
+
], []));
|
|
419
|
+
}
|
|
420
|
+
// ── Form association ─────────────────────────────────────────────────────
|
|
421
|
+
static formAssociated = true;
|
|
422
|
+
_internals = (_initProto(this), this.attachInternals());
|
|
423
|
+
#___private_status_1 = _init_status(this, 'default');
|
|
424
|
+
get status() {
|
|
425
|
+
return this.#___private_status_1;
|
|
426
|
+
}
|
|
427
|
+
set status(_v) {
|
|
428
|
+
this.#___private_status_1 = _v;
|
|
429
|
+
}
|
|
430
|
+
#___private_required_2 = _init_required(this, false);
|
|
431
|
+
get required() {
|
|
432
|
+
return this.#___private_required_2;
|
|
433
|
+
}
|
|
434
|
+
set required(_v) {
|
|
435
|
+
this.#___private_required_2 = _v;
|
|
436
|
+
}
|
|
437
|
+
#___private_validityMessage_3 = _init_validityMessage(this, '');
|
|
438
|
+
get validityMessage() {
|
|
439
|
+
return this.#___private_validityMessage_3;
|
|
440
|
+
}
|
|
441
|
+
set validityMessage(_v) {
|
|
442
|
+
this.#___private_validityMessage_3 = _v;
|
|
443
|
+
}
|
|
444
|
+
// ── ValidityState getters (WHATWG Constraint Validation API) ──────────────
|
|
445
|
+
/**
|
|
446
|
+
* The ValidityState from ElementInternals.
|
|
447
|
+
* Always reflects the most recent `_testValidity()` result.
|
|
448
|
+
*/ get validity() {
|
|
449
|
+
return this._internals.validity;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* The human-readable validation message from ElementInternals.
|
|
453
|
+
* Set by `setValidity()` and `setCustomValidity()`.
|
|
454
|
+
*/ get validationMessage() {
|
|
455
|
+
return this._internals.validationMessage;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Whether this control will participate in form validation.
|
|
459
|
+
* Per spec, disabled controls return false (they are not candidates).
|
|
460
|
+
*/ get willValidate() {
|
|
461
|
+
return this._internals.willValidate;
|
|
462
|
+
}
|
|
463
|
+
// ── Extension hooks for subclasses ────────────────────────────────────────
|
|
464
|
+
/**
|
|
465
|
+
* Returns ValidityStateFlags describing why the current value is invalid.
|
|
466
|
+
* Return `{}` (empty) when the value is valid.
|
|
467
|
+
*
|
|
468
|
+
* Subclasses MUST override this. The base implementation returns `{}`
|
|
469
|
+
* (always valid) as a safe default.
|
|
470
|
+
*/ _testValidity() {
|
|
471
|
+
return {};
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Returns the element that browser validation popups should anchor to.
|
|
475
|
+
* Override in subclasses that wrap a native control via FocusableMixin.
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
478
|
+
* protected override _getValidationAnchor(): HTMLElement | undefined {
|
|
479
|
+
* return this._focusableElement ?? undefined;
|
|
480
|
+
* }
|
|
481
|
+
*/ _getValidationAnchor() {
|
|
482
|
+
return undefined;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Internal validity check — sets validity on ElementInternals and
|
|
486
|
+
* dispatches the cancelable `invalid` event if invalid.
|
|
487
|
+
* Returns whether the control is valid and whether the event was allowed.
|
|
488
|
+
*/ _checkValidityAndDispatch() {
|
|
489
|
+
const flags = this._testValidity();
|
|
490
|
+
const isValid = !Object.values(flags).some(Boolean);
|
|
491
|
+
const anchor = this._getValidationAnchor();
|
|
492
|
+
if (isValid) {
|
|
493
|
+
this._internals.setValidity({});
|
|
494
|
+
} else {
|
|
495
|
+
const msg = this.validityMessage || 'Invalid value';
|
|
496
|
+
if (anchor) {
|
|
497
|
+
this._internals.setValidity(flags, msg, anchor);
|
|
498
|
+
} else {
|
|
499
|
+
this._internals.setValidity(flags, msg);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
let proceed = true;
|
|
503
|
+
if (!isValid) {
|
|
504
|
+
proceed = this.dispatchEvent(new Event('invalid', {
|
|
505
|
+
bubbles: false,
|
|
506
|
+
cancelable: true,
|
|
507
|
+
composed: false
|
|
508
|
+
}));
|
|
509
|
+
}
|
|
510
|
+
return {
|
|
511
|
+
isValid,
|
|
512
|
+
proceed
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Checks whether the control satisfies all validity constraints.
|
|
517
|
+
*
|
|
518
|
+
* Per the WHATWG spec, this method:
|
|
519
|
+
* - Evaluates validity via `_testValidity()`
|
|
520
|
+
* - Updates `_internals.setValidity()` so `.validity` is fresh
|
|
521
|
+
* - Dispatches a cancelable `invalid` event if the control is invalid
|
|
522
|
+
* - Returns `true` if valid, `false` otherwise
|
|
523
|
+
*
|
|
524
|
+
* **Does NOT mutate `status`.** Use `reportValidity()` to update
|
|
525
|
+
* the visual state.
|
|
526
|
+
*/ checkValidity() {
|
|
527
|
+
return this._checkValidityAndDispatch().isValid;
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Checks validity, updates the visual `status` (if the `invalid` event
|
|
531
|
+
* was not prevented), and triggers the browser's built-in validation popup.
|
|
532
|
+
*
|
|
533
|
+
* This is the method that should be called when you want the user
|
|
534
|
+
* to see validation feedback.
|
|
535
|
+
*/ reportValidity() {
|
|
536
|
+
const { isValid, proceed } = this._checkValidityAndDispatch();
|
|
537
|
+
if (isValid) {
|
|
538
|
+
if (this.status === 'invalid') {
|
|
539
|
+
this.status = 'default';
|
|
540
|
+
this.validityMessage = '';
|
|
541
|
+
}
|
|
542
|
+
} else {
|
|
543
|
+
// Only update visual status if the `invalid` event wasn't prevented
|
|
544
|
+
if (proceed) {
|
|
545
|
+
this.status = 'invalid';
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return this._internals.reportValidity();
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Sets or clears a custom validation error.
|
|
552
|
+
*
|
|
553
|
+
* - Pass a non-empty string to mark the control as invalid with a custom message.
|
|
554
|
+
* - Pass an empty string to clear the custom error.
|
|
555
|
+
*/ setCustomValidity(message) {
|
|
556
|
+
const hasError = Boolean(message);
|
|
557
|
+
this.status = hasError ? 'invalid' : 'default';
|
|
558
|
+
this.validityMessage = message;
|
|
559
|
+
if (hasError) {
|
|
560
|
+
const anchor = this._getValidationAnchor();
|
|
561
|
+
if (anchor) {
|
|
562
|
+
this._internals.setValidity({
|
|
563
|
+
customError: true
|
|
564
|
+
}, message, anchor);
|
|
565
|
+
} else {
|
|
566
|
+
this._internals.setValidity({
|
|
567
|
+
customError: true
|
|
568
|
+
}, message);
|
|
569
|
+
}
|
|
570
|
+
} else {
|
|
571
|
+
this._internals.setValidity({});
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
// ── Auto re-validation (keeps .validity fresh) ───────────────────────────
|
|
575
|
+
/**
|
|
576
|
+
* Silently keeps `_internals.setValidity()` in sync whenever reactive
|
|
577
|
+
* properties change. This ensures `.validity` is always fresh without
|
|
578
|
+
* mutating `status` or dispatching events.
|
|
579
|
+
*/ updated(changed) {
|
|
580
|
+
super.updated(changed);
|
|
581
|
+
if (changed.has('value') || changed.has('required')) {
|
|
582
|
+
this._syncValidity();
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Internal validity sync — updates `_internals.setValidity()` without
|
|
587
|
+
* changing visual `status` or dispatching events.
|
|
588
|
+
*/ _syncValidity() {
|
|
589
|
+
const flags = this._testValidity();
|
|
590
|
+
const isValid = !Object.values(flags).some(Boolean);
|
|
591
|
+
const anchor = this._getValidationAnchor();
|
|
592
|
+
if (isValid) {
|
|
593
|
+
this._internals.setValidity({});
|
|
594
|
+
} else {
|
|
595
|
+
const msg = this.validityMessage || 'Invalid value';
|
|
596
|
+
if (anchor) {
|
|
597
|
+
this._internals.setValidity(flags, msg, anchor);
|
|
598
|
+
} else {
|
|
599
|
+
this._internals.setValidity(flags, msg);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
// ── Form lifecycle callbacks ─────────────────────────────────────────────
|
|
604
|
+
/**
|
|
605
|
+
* Called when the associated `<form>` is reset.
|
|
606
|
+
* Resets visual status and validation message.
|
|
607
|
+
*
|
|
608
|
+
* Subclasses should override to also reset their `value` property,
|
|
609
|
+
* then call `super.formResetCallback()`.
|
|
610
|
+
*/ formResetCallback() {
|
|
611
|
+
this.status = 'default';
|
|
612
|
+
this.validityMessage = '';
|
|
613
|
+
this._internals.setValidity({});
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Called when the form or parent `<fieldset>` disabled state changes.
|
|
617
|
+
* Propagates the disabled state to the element's `disabled` property.
|
|
618
|
+
*/ formDisabledCallback(disabled) {
|
|
619
|
+
// All consumers declare `disabled` as @property — set it directly.
|
|
620
|
+
this.disabled = disabled;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Called when the browser restores form state (back/forward cache, autofill).
|
|
624
|
+
* Default implementation handles string values. Override for complex types
|
|
625
|
+
* (arrays, FormData, etc.).
|
|
626
|
+
*/ formStateRestoreCallback(state, _reason) {
|
|
627
|
+
if (typeof state === 'string') {
|
|
628
|
+
this.value = state;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return ValidityMixinClass;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
export { ValidityMixin as V };
|