@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.
@@ -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 };