@italia/input 0.1.0-alpha.0 → 1.0.0-alpha.4
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 +1 -1
- package/custom-elements.json +353 -307
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/it-input.d.ts +25 -1077
- package/dist/src/it-input.d.ts.map +1 -1
- package/dist/src/it-input.js +1069 -513
- package/dist/src/it-input.js.map +1 -1
- package/dist/src/locales/it.d.ts.map +1 -1
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +17 -14
- package/styles/globals.scss +15 -6
package/dist/src/it-input.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { directive, Directive } from 'lit/directive.js';
|
|
2
2
|
import { LitElement, css, html, nothing } from 'lit';
|
|
3
|
-
import {
|
|
3
|
+
import { state, query, property, queryAssignedElements, customElement } from 'lit/decorators.js';
|
|
4
4
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
5
|
import { when } from 'lit/directives/when.js';
|
|
6
|
+
import { live } from 'lit/directives/live.js';
|
|
6
7
|
|
|
7
8
|
/******************************************************************************
|
|
8
9
|
Copyright (c) Microsoft Corporation.
|
|
@@ -37,209 +38,6 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
37
38
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
38
39
|
};
|
|
39
40
|
|
|
40
|
-
/**
|
|
41
|
-
* @license
|
|
42
|
-
*
|
|
43
|
-
* Copyright IBM Corp. 2020, 2022
|
|
44
|
-
*
|
|
45
|
-
* This source code is licensed under the Apache-2.0 license found in the
|
|
46
|
-
* LICENSE file in the root directory of this source tree.
|
|
47
|
-
*/
|
|
48
|
-
/**
|
|
49
|
-
* @param Base The base class.
|
|
50
|
-
* @returns A mix-in to handle `formdata` event on the containing form.
|
|
51
|
-
*/
|
|
52
|
-
const FormMixin = (Base) => {
|
|
53
|
-
/**
|
|
54
|
-
* A mix-in class to handle `formdata` event on the containing form.
|
|
55
|
-
*/
|
|
56
|
-
class FormMixinImpl extends Base {
|
|
57
|
-
connectedCallback() {
|
|
58
|
-
// @ts-ignore
|
|
59
|
-
super.connectedCallback();
|
|
60
|
-
if (this.closest('form')) {
|
|
61
|
-
this.closest('form')?.addEventListener('formdata', this._handleFormdata.bind(this));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
disconnectedCallback() {
|
|
65
|
-
// if (this._hFormdata) {
|
|
66
|
-
// this._hFormdata = this._hFormdata.release();
|
|
67
|
-
// }
|
|
68
|
-
// @ts-ignore
|
|
69
|
-
super.disconnectedCallback();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return FormMixinImpl;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* @license
|
|
77
|
-
*
|
|
78
|
-
* Copyright IBM Corp. 2020, 2022
|
|
79
|
-
*
|
|
80
|
-
* This source code is licensed under the Apache-2.0 license found in the
|
|
81
|
-
* LICENSE file in the root directory of this source tree.
|
|
82
|
-
*/
|
|
83
|
-
/**
|
|
84
|
-
* Form validation status.
|
|
85
|
-
*/
|
|
86
|
-
var VALIDATION_STATUS;
|
|
87
|
-
(function (VALIDATION_STATUS) {
|
|
88
|
-
/**
|
|
89
|
-
* One indicating no validation error.
|
|
90
|
-
*/
|
|
91
|
-
VALIDATION_STATUS["NO_ERROR"] = "";
|
|
92
|
-
/**
|
|
93
|
-
* One indicating that the value is invalid (generic).
|
|
94
|
-
*/
|
|
95
|
-
VALIDATION_STATUS["INVALID"] = "invalid";
|
|
96
|
-
/**
|
|
97
|
-
* One indicating missing required value.
|
|
98
|
-
*/
|
|
99
|
-
VALIDATION_STATUS["ERROR_REQUIRED"] = "required";
|
|
100
|
-
/**
|
|
101
|
-
* One indicating that the value does not match the pattern.
|
|
102
|
-
*/
|
|
103
|
-
VALIDATION_STATUS["PATTERN"] = "pattern";
|
|
104
|
-
/**
|
|
105
|
-
* One indicating that the value is shorter than the minimum length.
|
|
106
|
-
*/
|
|
107
|
-
VALIDATION_STATUS["MINLENGTH"] = "minlength";
|
|
108
|
-
/**
|
|
109
|
-
* One indicating that the value is less than the maximum length.
|
|
110
|
-
*/
|
|
111
|
-
VALIDATION_STATUS["MAXLENGTH"] = "maxlength";
|
|
112
|
-
})(VALIDATION_STATUS || (VALIDATION_STATUS = {}));
|
|
113
|
-
/**
|
|
114
|
-
* @param Base The base class.
|
|
115
|
-
* @returns A mix-in implementing `.setCustomValidity()` method.
|
|
116
|
-
*/
|
|
117
|
-
const ValidityMixin = (Base) => {
|
|
118
|
-
class ValidityMixinImpl extends Base {
|
|
119
|
-
constructor() {
|
|
120
|
-
super(...arguments);
|
|
121
|
-
/**
|
|
122
|
-
* Field is touched
|
|
123
|
-
*/
|
|
124
|
-
this._touched = false;
|
|
125
|
-
}
|
|
126
|
-
// Not using TypeScript `protected` due to: microsoft/TypeScript#17744
|
|
127
|
-
// Using `string` instead of `VALIDATION_STATUS` until we can require TypeScript 3.8
|
|
128
|
-
/**
|
|
129
|
-
* @param state The form validation status.
|
|
130
|
-
* @returns The form validation error mesasages associated with the given status.
|
|
131
|
-
* @protected
|
|
132
|
-
*/
|
|
133
|
-
_getValidityMessage(state, translations) {
|
|
134
|
-
return {
|
|
135
|
-
[VALIDATION_STATUS.NO_ERROR]: '',
|
|
136
|
-
[VALIDATION_STATUS.INVALID]: translations[VALIDATION_STATUS.INVALID],
|
|
137
|
-
[VALIDATION_STATUS.ERROR_REQUIRED]: translations[VALIDATION_STATUS.ERROR_REQUIRED],
|
|
138
|
-
[VALIDATION_STATUS.PATTERN]: translations[VALIDATION_STATUS.PATTERN],
|
|
139
|
-
[VALIDATION_STATUS.MINLENGTH]: translations[VALIDATION_STATUS.MINLENGTH].replace('{minlength}', this.minlength.toString()),
|
|
140
|
-
[VALIDATION_STATUS.MAXLENGTH]: translations[VALIDATION_STATUS.MAXLENGTH].replace('{maxlength}', this.maxlength.toString()),
|
|
141
|
-
}[state];
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Checks if the value meets the constraints.
|
|
145
|
-
*
|
|
146
|
-
* @returns `true` if the value meets the constraints. `false` otherwise.
|
|
147
|
-
*/
|
|
148
|
-
_checkValidity(translations, htmlValidity = true) {
|
|
149
|
-
// htmlValidity = this.inputElement.checkValidity(); //check browser validity
|
|
150
|
-
if (this.customValidation) {
|
|
151
|
-
return undefined;
|
|
152
|
-
}
|
|
153
|
-
let validity = htmlValidity;
|
|
154
|
-
let message = validity
|
|
155
|
-
? this._getValidityMessage(VALIDATION_STATUS.NO_ERROR, translations)
|
|
156
|
-
: this._getValidityMessage(VALIDATION_STATUS.INVALID, translations);
|
|
157
|
-
if (this.required || (this._value && (this.pattern || this.minlength > 0 || this.maxlength > 0))) {
|
|
158
|
-
if (this.pattern) {
|
|
159
|
-
const regex = new RegExp(`^${this.pattern}$`, 'u');
|
|
160
|
-
validity = regex.test(this._value.toString());
|
|
161
|
-
if (!validity) {
|
|
162
|
-
message = this._getValidityMessage(VALIDATION_STATUS.PATTERN, translations);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
if (typeof this.minlength !== 'undefined' && this.minlength > 0) {
|
|
166
|
-
validity = validity && this._value.toString().length >= this.minlength;
|
|
167
|
-
if (!validity) {
|
|
168
|
-
message = this._getValidityMessage(VALIDATION_STATUS.MINLENGTH, translations);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
if (typeof this.maxlength !== 'undefined' && this.maxlength > 0) {
|
|
172
|
-
validity = validity && this._value.toString().length <= this.maxlength;
|
|
173
|
-
if (!validity) {
|
|
174
|
-
message = this._getValidityMessage(VALIDATION_STATUS.MAXLENGTH, translations);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if (this.required && !this._value) {
|
|
178
|
-
validity = false;
|
|
179
|
-
message = this._getValidityMessage(VALIDATION_STATUS.ERROR_REQUIRED, translations);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
this.invalid = !validity;
|
|
183
|
-
this.validityMessage = message;
|
|
184
|
-
return validity;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Sets the given custom validity message.
|
|
188
|
-
*
|
|
189
|
-
* @param validityMessage The custom validity message
|
|
190
|
-
*/
|
|
191
|
-
setCustomValidity(validityMessage) {
|
|
192
|
-
this.invalid = Boolean(validityMessage);
|
|
193
|
-
this.validityMessage = validityMessage;
|
|
194
|
-
}
|
|
195
|
-
_handleBlur() {
|
|
196
|
-
this._touched = true;
|
|
197
|
-
this.dispatchEvent(new FocusEvent('blur', { bubbles: true, composed: true }));
|
|
198
|
-
}
|
|
199
|
-
_handleFocus() {
|
|
200
|
-
this.dispatchEvent(new FocusEvent('focus', { bubbles: true, composed: true }));
|
|
201
|
-
}
|
|
202
|
-
_handleClick() {
|
|
203
|
-
this.dispatchEvent(new MouseEvent('click', { bubbles: true, composed: true }));
|
|
204
|
-
}
|
|
205
|
-
_handleChange(e) {
|
|
206
|
-
const target = e.target;
|
|
207
|
-
let value;
|
|
208
|
-
if (target instanceof HTMLInputElement) {
|
|
209
|
-
switch (target.type) {
|
|
210
|
-
case 'checkbox':
|
|
211
|
-
case 'radio':
|
|
212
|
-
value = target.checked;
|
|
213
|
-
break;
|
|
214
|
-
case 'file':
|
|
215
|
-
value = target.files; // FileList
|
|
216
|
-
break;
|
|
217
|
-
default:
|
|
218
|
-
value = target.value;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
else if (target instanceof HTMLSelectElement) {
|
|
222
|
-
if (target.multiple) {
|
|
223
|
-
value = Array.from(target.selectedOptions).map((o) => o.value);
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
value = target.value;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
// textarea o altri input con value
|
|
231
|
-
value = target.value;
|
|
232
|
-
}
|
|
233
|
-
this.dispatchEvent(new CustomEvent('change', {
|
|
234
|
-
detail: { value, el: target },
|
|
235
|
-
bubbles: true,
|
|
236
|
-
composed: true,
|
|
237
|
-
}));
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return ValidityMixinImpl;
|
|
241
|
-
};
|
|
242
|
-
|
|
243
41
|
class SetAttributesDirective extends Directive {
|
|
244
42
|
update(part, [attributes]) {
|
|
245
43
|
const el = part.element;
|
|
@@ -262,6 +60,8 @@ class SetAttributesDirective extends Directive {
|
|
|
262
60
|
*/
|
|
263
61
|
const setAttributes = directive(SetAttributesDirective);
|
|
264
62
|
|
|
63
|
+
function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
|
|
64
|
+
|
|
265
65
|
const connectedElements = new Set();
|
|
266
66
|
if (window && !window.translations) {
|
|
267
67
|
window.translations = new Map();
|
|
@@ -471,10 +271,11 @@ const LocalizeMixin = (Base) => class extends Base {
|
|
|
471
271
|
constructor() {
|
|
472
272
|
super(...arguments);
|
|
473
273
|
this.localize = new LocalizeController(this);
|
|
474
|
-
// Provide default values to avoid definite assignment errors and avoid decorators
|
|
475
|
-
this.dir = '';
|
|
476
|
-
this.lang = '';
|
|
477
274
|
}
|
|
275
|
+
// Provide default values to avoid definite assignment errors and avoid decorators
|
|
276
|
+
// commentati perchè danno problemi su React.js. Sono attributi nativi, e assegnare un valore di default a react da fastidio
|
|
277
|
+
// dir: string = '';
|
|
278
|
+
// lang: string = '';
|
|
478
279
|
/**
|
|
479
280
|
* Restituisce tutta l'utility di traduzione
|
|
480
281
|
*
|
|
@@ -560,50 +361,729 @@ class Logger {
|
|
|
560
361
|
}
|
|
561
362
|
}
|
|
562
363
|
|
|
563
|
-
/**
|
|
564
|
-
* Factory function per creare una base class estendibile
|
|
565
|
-
* con stili personalizzati.
|
|
566
|
-
*/
|
|
567
|
-
class BaseComponent extends LitElement {
|
|
568
|
-
constructor() {
|
|
569
|
-
super();
|
|
570
|
-
this.
|
|
571
|
-
this.logger = new Logger(this.tagName.toLowerCase());
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
364
|
+
/**
|
|
365
|
+
* Factory function per creare una base class estendibile
|
|
366
|
+
* con stili personalizzati.
|
|
367
|
+
*/
|
|
368
|
+
class BaseComponent extends LitElement {
|
|
369
|
+
constructor() {
|
|
370
|
+
super();
|
|
371
|
+
this.composeClass = clsx;
|
|
372
|
+
this.logger = new Logger(this.tagName.toLowerCase());
|
|
373
|
+
}
|
|
374
|
+
get _ariaAttributes() {
|
|
375
|
+
const attributes = {};
|
|
376
|
+
for (const attr of this.getAttributeNames()) {
|
|
377
|
+
if (attr === 'it-role') {
|
|
378
|
+
attributes.role = this.getAttribute(attr);
|
|
379
|
+
}
|
|
380
|
+
else if (attr.startsWith('it-aria-')) {
|
|
381
|
+
attributes[attr.replace(/^it-/, '')] = this.getAttribute(attr);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return attributes;
|
|
385
|
+
}
|
|
386
|
+
// eslint-disable-next-line class-methods-use-this
|
|
387
|
+
generateId(prefix) {
|
|
388
|
+
return `${prefix}-${Math.random().toString(36).slice(2)}`;
|
|
389
|
+
}
|
|
390
|
+
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars
|
|
391
|
+
addFocus(element) {
|
|
392
|
+
// new TrackFocus(element); // per il momento è stato disattivato perchè ci sono le pseudo classi ::focus-visible per fare quello che fa TrackFocus. Si possono aggiungere regole css in bsi-italia 3 dato che stiamo facendo una breaking release di bsi.
|
|
393
|
+
}
|
|
394
|
+
// eslint-disable-next-line class-methods-use-this
|
|
395
|
+
getActiveElement() {
|
|
396
|
+
let active = document.activeElement;
|
|
397
|
+
while (active && active.shadowRoot && active.shadowRoot.activeElement) {
|
|
398
|
+
active = active.shadowRoot.activeElement;
|
|
399
|
+
}
|
|
400
|
+
return active;
|
|
401
|
+
}
|
|
402
|
+
get focusElement() {
|
|
403
|
+
return this;
|
|
404
|
+
}
|
|
405
|
+
// eslint-disable-next-line class-methods-use-this
|
|
406
|
+
get prefersReducedMotion() {
|
|
407
|
+
return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
408
|
+
}
|
|
409
|
+
connectedCallback() {
|
|
410
|
+
super.connectedCallback();
|
|
411
|
+
// generate internal _id
|
|
412
|
+
const prefix = this.id?.length > 0 ? this.id : this.tagName.toLowerCase();
|
|
413
|
+
this._id = this.generateId(prefix);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const BaseLocalizedComponent = LocalizeMixin(BaseComponent);
|
|
417
|
+
|
|
418
|
+
//
|
|
419
|
+
// We store a WeakMap of forms + controls so we can keep references to all FormControl within a given form. As
|
|
420
|
+
// elements connect and disconnect to/from the DOM, their containing form is used as the key and the form control is
|
|
421
|
+
// added and removed from the form's set, respectively.
|
|
422
|
+
//
|
|
423
|
+
const formCollections = new WeakMap();
|
|
424
|
+
//
|
|
425
|
+
// We store a WeakMap of reportValidity() overloads so we can override it when form controls connect to the DOM and
|
|
426
|
+
// restore the original behavior when they disconnect.
|
|
427
|
+
//
|
|
428
|
+
const reportValidityOverloads = new WeakMap();
|
|
429
|
+
const checkValidityOverloads = new WeakMap();
|
|
430
|
+
//
|
|
431
|
+
// We store a Set of controls that users have interacted with. This allows us to determine the interaction state
|
|
432
|
+
// without littering the DOM with additional data attributes.
|
|
433
|
+
//
|
|
434
|
+
const userInteractedControls = new WeakSet();
|
|
435
|
+
//
|
|
436
|
+
// We store a WeakMap of interactions for each form control so we can track when all conditions are met for validation.
|
|
437
|
+
//
|
|
438
|
+
const interactions = new WeakMap();
|
|
439
|
+
/** A reactive controller to allow form controls to participate in form submission, validation, etc. */
|
|
440
|
+
class FormControlController {
|
|
441
|
+
constructor(host, options) {
|
|
442
|
+
this.submittedOnce = false;
|
|
443
|
+
this.handleFormData = (event) => {
|
|
444
|
+
// console.log('handleFormData');
|
|
445
|
+
const disabled = this.options.disabled(this.host);
|
|
446
|
+
const name = this.options.name(this.host);
|
|
447
|
+
const value = this.options.value(this.host);
|
|
448
|
+
const tagName = this.host.tagName.toLowerCase();
|
|
449
|
+
// For buttons, we only submit the value if they were the submitter. This is currently done in doAction() by
|
|
450
|
+
// injecting the name/value on a temporary button, so we can just skip them here.
|
|
451
|
+
const isButton = tagName === 'it-button';
|
|
452
|
+
if (this.host.isConnected &&
|
|
453
|
+
!disabled &&
|
|
454
|
+
!isButton &&
|
|
455
|
+
typeof name === 'string' &&
|
|
456
|
+
name.length > 0 &&
|
|
457
|
+
typeof value !== 'undefined') {
|
|
458
|
+
switch (tagName) {
|
|
459
|
+
case 'it-radio':
|
|
460
|
+
if (this.host.checked) {
|
|
461
|
+
event.formData.append(name, value);
|
|
462
|
+
}
|
|
463
|
+
break;
|
|
464
|
+
case 'it-checkbox':
|
|
465
|
+
if (this.host.checked) {
|
|
466
|
+
if (event.formData.getAll(name).indexOf(value) < 0) {
|
|
467
|
+
// handle group checkbox
|
|
468
|
+
event.formData.append(name, value);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
break;
|
|
472
|
+
case 'it-checkbox-group':
|
|
473
|
+
// non settare valori in formData, perchè ogni singola checkbox setta il suo valore
|
|
474
|
+
break;
|
|
475
|
+
default:
|
|
476
|
+
if (Array.isArray(value)) {
|
|
477
|
+
value.forEach((val) => {
|
|
478
|
+
event.formData.append(name, val.toString());
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
event.formData.append(name, value.toString());
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
this.handleFormSubmit = (event) => {
|
|
488
|
+
const disabled = this.options.disabled(this.host);
|
|
489
|
+
const reportValidity = this.options.reportValidity;
|
|
490
|
+
// Update the interacted state for all controls when the form is submitted
|
|
491
|
+
if (this.form && !this.form.noValidate) {
|
|
492
|
+
formCollections.get(this.form)?.forEach((control) => {
|
|
493
|
+
this.setUserInteracted(control, true);
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
const resReportValidity = reportValidity(this.host);
|
|
497
|
+
if (this.form && !this.form.noValidate && !disabled && !resReportValidity) {
|
|
498
|
+
event.preventDefault();
|
|
499
|
+
// event.stopImmediatePropagation(); // se lo attiviamo, valida un campo alla volta
|
|
500
|
+
// Scroll al primo controllo non valido
|
|
501
|
+
const formControls = formCollections.get(this.form);
|
|
502
|
+
if (formControls) {
|
|
503
|
+
for (const control of formControls) {
|
|
504
|
+
if (!control.validity?.valid) {
|
|
505
|
+
// Scroll smooth verso il controllo non valido
|
|
506
|
+
control.scrollIntoView({
|
|
507
|
+
behavior: 'smooth',
|
|
508
|
+
block: 'center',
|
|
509
|
+
});
|
|
510
|
+
break;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
this.submittedOnce = true;
|
|
516
|
+
};
|
|
517
|
+
this.handleFormReset = () => {
|
|
518
|
+
this.options.setValue(this.host, '');
|
|
519
|
+
this.submittedOnce = false;
|
|
520
|
+
this.setUserInteracted(this.host, false);
|
|
521
|
+
interactions.set(this.host, []);
|
|
522
|
+
};
|
|
523
|
+
this.handleInteraction = (event) => {
|
|
524
|
+
const emittedEvents = interactions.get(this.host);
|
|
525
|
+
if (!emittedEvents.includes(event.type)) {
|
|
526
|
+
emittedEvents.push(event.type);
|
|
527
|
+
}
|
|
528
|
+
// Mark it as user-interacted as soon as all associated events have been emitted
|
|
529
|
+
if (emittedEvents.length === this.options.assumeInteractionOn.length) {
|
|
530
|
+
this.setUserInteracted(this.host, true);
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
this.checkFormValidity = () => {
|
|
534
|
+
// console.log('checkFormValidity');
|
|
535
|
+
//
|
|
536
|
+
// This is very similar to the `reportFormValidity` function, but it does not trigger native constraint validation
|
|
537
|
+
// Allow the user to simply check if the form is valid and handling validity in their own way.
|
|
538
|
+
//
|
|
539
|
+
// We preserve the original method in a WeakMap, but we don't call it from the overload because that would trigger
|
|
540
|
+
// validations in an unexpected order. When the element disconnects, we revert to the original behavior. This won't
|
|
541
|
+
// be necessary once we can use ElementInternals.
|
|
542
|
+
//
|
|
543
|
+
// Note that we're also honoring the form's novalidate attribute.
|
|
544
|
+
//
|
|
545
|
+
if (this.form && !this.form.noValidate) {
|
|
546
|
+
// This seems sloppy, but checking all elements will cover native inputs, Shoelace inputs, and other custom
|
|
547
|
+
// elements that support the constraint validation API.
|
|
548
|
+
const elements = this.form.querySelectorAll('*');
|
|
549
|
+
for (const element of elements) {
|
|
550
|
+
if (typeof element.checkValidity === 'function') {
|
|
551
|
+
if (!element.checkValidity()) {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return true;
|
|
558
|
+
};
|
|
559
|
+
this.reportFormValidity = () => {
|
|
560
|
+
// console.log('reportFormValidity');
|
|
561
|
+
//
|
|
562
|
+
// FormControl work hard to act like regular form controls. They support the Constraint Validation API
|
|
563
|
+
// and its associated methods such as setCustomValidity() and reportValidity(). However, the HTMLFormElement also
|
|
564
|
+
// has a reportValidity() method that will trigger validation on all child controls. Since we're not yet using
|
|
565
|
+
// ElementInternals, we need to overload this method so it looks for any element with the reportValidity() method.
|
|
566
|
+
//
|
|
567
|
+
// We preserve the original method in a WeakMap, but we don't call it from the overload because that would trigger
|
|
568
|
+
// validations in an unexpected order. When the element disconnects, we revert to the original behavior. This won't
|
|
569
|
+
// be necessary once we can use ElementInternals.
|
|
570
|
+
//
|
|
571
|
+
// Note that we're also honoring the form's novalidate attribute.
|
|
572
|
+
//
|
|
573
|
+
if (this.form && !this.form.noValidate) {
|
|
574
|
+
// This seems sloppy, but checking all elements will cover native inputs, Shoelace inputs, and other custom
|
|
575
|
+
// elements that support the constraint validation API.
|
|
576
|
+
const elements = this.form.querySelectorAll('*');
|
|
577
|
+
for (const element of elements) {
|
|
578
|
+
if (typeof element.reportValidity === 'function') {
|
|
579
|
+
if (!element.reportValidity()) {
|
|
580
|
+
return false;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
return true;
|
|
586
|
+
};
|
|
587
|
+
(this.host = host).addController(this);
|
|
588
|
+
this.options = {
|
|
589
|
+
form: (input) => {
|
|
590
|
+
// If there's a form attribute, use it to find the target form by id
|
|
591
|
+
// Controls may not always reflect the 'form' property. For example, `<it-button>` doesn't reflect.
|
|
592
|
+
const formId = input.form;
|
|
593
|
+
if (formId) {
|
|
594
|
+
const root = input.getRootNode();
|
|
595
|
+
const form = root.querySelector(`#${formId}`);
|
|
596
|
+
if (form) {
|
|
597
|
+
return form;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
return input.closest('form');
|
|
601
|
+
},
|
|
602
|
+
name: (input) => input.name,
|
|
603
|
+
value: (input) => input.value,
|
|
604
|
+
disabled: (input) => input.disabled ?? false,
|
|
605
|
+
reportValidity: (input) => typeof input.reportValidity === 'function' ? input.reportValidity() : true,
|
|
606
|
+
checkValidity: (input) => (typeof input.checkValidity === 'function' ? input.checkValidity() : true),
|
|
607
|
+
setValue: (input, value) => {
|
|
608
|
+
// eslint-disable-next-line no-param-reassign
|
|
609
|
+
input.value = value;
|
|
610
|
+
},
|
|
611
|
+
assumeInteractionOn: ['it-input'],
|
|
612
|
+
...options,
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
hostConnected() {
|
|
616
|
+
const form = this.options.form(this.host);
|
|
617
|
+
if (form) {
|
|
618
|
+
this.attachForm(form);
|
|
619
|
+
}
|
|
620
|
+
// Listen for interactions
|
|
621
|
+
interactions.set(this.host, []);
|
|
622
|
+
this.options.assumeInteractionOn.forEach((event) => {
|
|
623
|
+
this.host.addEventListener(event, this.handleInteraction);
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
hostDisconnected() {
|
|
627
|
+
this.detachForm();
|
|
628
|
+
// Clean up interactions
|
|
629
|
+
interactions.delete(this.host);
|
|
630
|
+
this.options.assumeInteractionOn.forEach((event) => {
|
|
631
|
+
this.host.removeEventListener(event, this.handleInteraction);
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
hostUpdated() {
|
|
635
|
+
const form = this.options.form(this.host);
|
|
636
|
+
// Detach if the form no longer exists
|
|
637
|
+
if (!form) {
|
|
638
|
+
this.detachForm();
|
|
639
|
+
}
|
|
640
|
+
// If the form has changed, reattach it
|
|
641
|
+
if (form && this.form !== form) {
|
|
642
|
+
this.detachForm();
|
|
643
|
+
this.attachForm(form);
|
|
644
|
+
}
|
|
645
|
+
if (this.host.hasUpdated) {
|
|
646
|
+
this.setValidity(this.host.validity.valid);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
attachForm(form) {
|
|
650
|
+
if (form) {
|
|
651
|
+
this.form = form;
|
|
652
|
+
// Add this element to the form's collection
|
|
653
|
+
if (formCollections.has(this.form)) {
|
|
654
|
+
formCollections.get(this.form).add(this.host);
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
formCollections.set(this.form, new Set([this.host]));
|
|
658
|
+
}
|
|
659
|
+
this.form.addEventListener('formdata', this.handleFormData);
|
|
660
|
+
this.form.addEventListener('submit', this.handleFormSubmit);
|
|
661
|
+
this.form.addEventListener('reset', this.handleFormReset);
|
|
662
|
+
// Overload the form's reportValidity() method so it looks at FormControl
|
|
663
|
+
if (!reportValidityOverloads.has(this.form)) {
|
|
664
|
+
reportValidityOverloads.set(this.form, this.form.reportValidity);
|
|
665
|
+
this.form.reportValidity = () => this.reportFormValidity();
|
|
666
|
+
}
|
|
667
|
+
// Overload the form's checkValidity() method so it looks at FormControl
|
|
668
|
+
if (!checkValidityOverloads.has(this.form)) {
|
|
669
|
+
checkValidityOverloads.set(this.form, this.form.checkValidity);
|
|
670
|
+
this.form.checkValidity = () => this.checkFormValidity();
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
else {
|
|
674
|
+
this.form = undefined;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
detachForm() {
|
|
678
|
+
if (!this.form)
|
|
679
|
+
return;
|
|
680
|
+
const formCollection = formCollections.get(this.form);
|
|
681
|
+
if (!formCollection) {
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
this.submittedOnce = false;
|
|
685
|
+
// Remove this host from the form's collection
|
|
686
|
+
formCollection.delete(this.host);
|
|
687
|
+
// Check to make sure there's no other form controls in the collection. If we do this
|
|
688
|
+
// without checking if any other controls are still in the collection, then we will wipe out the
|
|
689
|
+
// validity checks for all other elements.
|
|
690
|
+
// see: https://github.com/shoelace-style/shoelace/issues/1703
|
|
691
|
+
if (formCollection.size <= 0) {
|
|
692
|
+
this.form.removeEventListener('formdata', this.handleFormData);
|
|
693
|
+
this.form.removeEventListener('submit', this.handleFormSubmit);
|
|
694
|
+
this.form.removeEventListener('reset', this.handleFormReset);
|
|
695
|
+
// Remove the overload and restore the original method
|
|
696
|
+
if (reportValidityOverloads.has(this.form)) {
|
|
697
|
+
this.form.reportValidity = reportValidityOverloads.get(this.form);
|
|
698
|
+
reportValidityOverloads.delete(this.form);
|
|
699
|
+
}
|
|
700
|
+
if (checkValidityOverloads.has(this.form)) {
|
|
701
|
+
this.form.checkValidity = checkValidityOverloads.get(this.form);
|
|
702
|
+
checkValidityOverloads.delete(this.form);
|
|
703
|
+
}
|
|
704
|
+
// So it looks weird here to not always set the form to undefined. But I _think_ if we unattach this.form here,
|
|
705
|
+
// we end up in this fun spot where future validity checks don't have a reference to the form validity handler.
|
|
706
|
+
// First form element in sets the validity handler. So we can't clean up `this.form` until there are no other form elements in the form.
|
|
707
|
+
this.form = undefined;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
// eslint-disable-next-line class-methods-use-this
|
|
711
|
+
setUserInteracted(el, hasInteracted) {
|
|
712
|
+
if (hasInteracted) {
|
|
713
|
+
userInteractedControls.add(el);
|
|
714
|
+
}
|
|
715
|
+
else {
|
|
716
|
+
userInteractedControls.delete(el);
|
|
717
|
+
}
|
|
718
|
+
el.requestUpdate();
|
|
719
|
+
}
|
|
720
|
+
doAction(type, submitter) {
|
|
721
|
+
// console.log('doaction', type);
|
|
722
|
+
if (this.form) {
|
|
723
|
+
const button = document.createElement('button');
|
|
724
|
+
button.type = type;
|
|
725
|
+
button.style.position = 'absolute';
|
|
726
|
+
button.style.width = '0';
|
|
727
|
+
button.style.height = '0';
|
|
728
|
+
button.style.clipPath = 'inset(50%)';
|
|
729
|
+
button.style.overflow = 'hidden';
|
|
730
|
+
button.style.whiteSpace = 'nowrap';
|
|
731
|
+
// Pass name, value, and form attributes through to the temporary button
|
|
732
|
+
if (submitter) {
|
|
733
|
+
button.name = submitter.name;
|
|
734
|
+
button.value = submitter.value;
|
|
735
|
+
['formaction', 'formenctype', 'formmethod', 'formnovalidate', 'formtarget'].forEach((attr) => {
|
|
736
|
+
if (submitter.hasAttribute(attr)) {
|
|
737
|
+
button.setAttribute(attr, submitter.getAttribute(attr));
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
this.form.append(button);
|
|
742
|
+
button.click();
|
|
743
|
+
button.remove();
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
/** Returns the associated `<form>` element, if one exists. */
|
|
747
|
+
getForm() {
|
|
748
|
+
return this.form ?? null;
|
|
749
|
+
}
|
|
750
|
+
/** Resets the form, restoring all the control to their default value */
|
|
751
|
+
reset(submitter) {
|
|
752
|
+
this.doAction('reset', submitter);
|
|
753
|
+
}
|
|
754
|
+
/** Submits the form, triggering validation and form data injection. */
|
|
755
|
+
submit(submitter) {
|
|
756
|
+
// Calling form.submit() bypasses the submit event and constraint validation. To prevent this, we can inject a
|
|
757
|
+
// native submit button into the form, "click" it, then remove it to simulate a standard form submission.
|
|
758
|
+
this.doAction('submit', submitter);
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Synchronously sets the form control's validity. Call this when you know the future validity but need to update
|
|
762
|
+
* the host element immediately, i.e. before Lit updates the component in the next update.
|
|
763
|
+
*/
|
|
764
|
+
setValidity(isValid) {
|
|
765
|
+
const host = this.host;
|
|
766
|
+
const hasInteracted = Boolean(userInteractedControls.has(host));
|
|
767
|
+
const required = Boolean(host.required);
|
|
768
|
+
//
|
|
769
|
+
// We're mapping the following "states" to data attributes. In the future, we can use ElementInternals.states to
|
|
770
|
+
// create a similar mapping, but instead of [data-invalid] it will look like :--invalid.
|
|
771
|
+
//
|
|
772
|
+
// See this RFC for more details: https://github.com/shoelace-style/shoelace/issues/1011
|
|
773
|
+
//
|
|
774
|
+
host.toggleAttribute('data-required', required);
|
|
775
|
+
host.toggleAttribute('data-optional', !required);
|
|
776
|
+
host.toggleAttribute('data-invalid', !isValid);
|
|
777
|
+
host.toggleAttribute('data-valid', isValid);
|
|
778
|
+
host.toggleAttribute('data-user-invalid', !isValid && hasInteracted);
|
|
779
|
+
host.toggleAttribute('data-user-valid', isValid && hasInteracted);
|
|
780
|
+
}
|
|
781
|
+
userInteracted() {
|
|
782
|
+
const hasInteracted = Boolean(userInteractedControls.has(this.host));
|
|
783
|
+
return hasInteracted;
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Updates the form control's validity based on the current value of `host.validity.valid`. Call this when anything
|
|
787
|
+
* that affects constraint validation changes so the component receives the correct validity states.
|
|
788
|
+
*/
|
|
789
|
+
updateValidity() {
|
|
790
|
+
const host = this.host;
|
|
791
|
+
this.setValidity(host.validity.valid);
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Dispatches a non-bubbling, cancelable custom event of type `it-invalid`.
|
|
795
|
+
* If the `it-invalid` event will be cancelled then the original `invalid`
|
|
796
|
+
* event (which may have been passed as argument) will also be cancelled.
|
|
797
|
+
* If no original `invalid` event has been passed then the `it-invalid`
|
|
798
|
+
* event will be cancelled before being dispatched.
|
|
799
|
+
*/
|
|
800
|
+
emitInvalidEvent(originalInvalidEvent) {
|
|
801
|
+
const itInvalidEvent = new CustomEvent('it-invalid', {
|
|
802
|
+
bubbles: false,
|
|
803
|
+
composed: false,
|
|
804
|
+
cancelable: true,
|
|
805
|
+
detail: {},
|
|
806
|
+
});
|
|
807
|
+
if (!originalInvalidEvent) {
|
|
808
|
+
itInvalidEvent.preventDefault();
|
|
809
|
+
}
|
|
810
|
+
if (!this.host.dispatchEvent(itInvalidEvent)) {
|
|
811
|
+
originalInvalidEvent?.preventDefault();
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
const translation$1 = {
|
|
817
|
+
$code: 'it',
|
|
818
|
+
$name: 'Italiano',
|
|
819
|
+
$dir: 'ltr',
|
|
820
|
+
validityRequired: 'Questo campo è obbligatorio.',
|
|
821
|
+
validityGroupRequired: "Scegli almeno un'opzione",
|
|
822
|
+
validityPattern: 'Il valore non corrisponde al formato richiesto.',
|
|
823
|
+
validityMinlength: 'Il valore deve essere lungo almeno {minlength} caratteri.',
|
|
824
|
+
validityMaxlength: 'Il valore deve essere lungo al massimo {maxlength} caratteri.',
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
registerTranslation(translation$1);
|
|
828
|
+
class FormControl extends BaseLocalizedComponent {
|
|
829
|
+
constructor() {
|
|
830
|
+
super(...arguments);
|
|
831
|
+
this.formControlController = new FormControlController(this, {
|
|
832
|
+
assumeInteractionOn: ['it-input', 'it-blur', 'it-change'],
|
|
833
|
+
});
|
|
834
|
+
// TODO: verificare se serve davvero con il fatto che usiamo form-controller
|
|
835
|
+
// static formAssociated = true;
|
|
836
|
+
// @property()
|
|
837
|
+
// internals = this.attachInternals();
|
|
838
|
+
this._touched = false;
|
|
839
|
+
/** The name of the input, submitted as a name/value pair with form data. */
|
|
840
|
+
this.name = '';
|
|
841
|
+
/** The current value of the input, submitted as a name/value pair with form data. */
|
|
842
|
+
this.value = '';
|
|
843
|
+
/** If the input is disabled. */
|
|
844
|
+
this.disabled = false;
|
|
845
|
+
/**
|
|
846
|
+
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
|
|
847
|
+
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
|
|
848
|
+
* the same document or shadow root for this to work.
|
|
849
|
+
*/
|
|
850
|
+
this.form = '';
|
|
851
|
+
/** If you implement your custom validation and you won't to trigger default validation */
|
|
852
|
+
this.customValidation = false;
|
|
853
|
+
/** If your input is invalid from your custom validition, set this attribute with message validation */
|
|
854
|
+
this.validationText = '';
|
|
855
|
+
/**
|
|
856
|
+
* Specifies the granularity that the value must adhere to, or the special value `any` which means no stepping is
|
|
857
|
+
* implied, allowing any numeric value. Only applies to date and number input types.
|
|
858
|
+
*/
|
|
859
|
+
this.step = 'any';
|
|
860
|
+
/** The input's minimum length. */
|
|
861
|
+
this.minlength = -1;
|
|
862
|
+
/** The input's maximum length. */
|
|
863
|
+
this.maxlength = -1;
|
|
864
|
+
/** If the input is required. */
|
|
865
|
+
this.required = false;
|
|
866
|
+
/* For grouped input, like checkbox-group */
|
|
867
|
+
this.isInGroup = false;
|
|
868
|
+
this.validationMessage = '';
|
|
869
|
+
}
|
|
870
|
+
/** Gets the validity state object */
|
|
871
|
+
get validity() {
|
|
872
|
+
return this.inputElement?.validity;
|
|
873
|
+
}
|
|
874
|
+
/** Gets the associated form, if one exists. */
|
|
875
|
+
getForm() {
|
|
876
|
+
return this.formControlController.getForm();
|
|
877
|
+
}
|
|
878
|
+
// Form validation methods
|
|
879
|
+
checkValidity() {
|
|
880
|
+
const inputValid = this.inputElement?.checkValidity() ?? true; // this.inputElement.checkValidity() è la validazione del browser
|
|
881
|
+
return inputValid;
|
|
882
|
+
}
|
|
883
|
+
/** Checks for validity and shows the browser's validation message if the control is invalid. */
|
|
884
|
+
reportValidity() {
|
|
885
|
+
// const ret = this.inputElement.checkValidity();
|
|
886
|
+
const ret = this.checkValidity(); // chiama la checkValidity, che se è stata overridata chiama quella
|
|
887
|
+
this.handleValidationMessages();
|
|
888
|
+
return ret; // this.inputElement.reportValidity();
|
|
889
|
+
}
|
|
890
|
+
/** Sets a custom validation message. Pass an empty string to restore validity. */
|
|
891
|
+
setCustomValidity(message) {
|
|
892
|
+
this.inputElement.setCustomValidity(message);
|
|
893
|
+
this.validationMessage = this.inputElement.validationMessage;
|
|
894
|
+
this.formControlController.updateValidity();
|
|
895
|
+
}
|
|
896
|
+
// Handlers
|
|
897
|
+
_handleReady() {
|
|
898
|
+
requestAnimationFrame(() => {
|
|
899
|
+
this.dispatchEvent(new CustomEvent('it-input-ready', { bubbles: true, detail: { el: this.inputElement } }));
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
903
|
+
_handleInput(e) {
|
|
904
|
+
this.handleValidationMessages();
|
|
905
|
+
this.dispatchEvent(new CustomEvent('it-input', {
|
|
906
|
+
detail: { value: this.inputElement.value, el: this.inputElement },
|
|
907
|
+
bubbles: true,
|
|
908
|
+
composed: true,
|
|
909
|
+
}));
|
|
910
|
+
}
|
|
911
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
912
|
+
_handleBlur(e) {
|
|
913
|
+
this._touched = true;
|
|
914
|
+
this.handleValidationMessages();
|
|
915
|
+
this.dispatchEvent(new FocusEvent('it-blur', { bubbles: true, composed: true }));
|
|
916
|
+
}
|
|
917
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
918
|
+
_handleFocus(e) {
|
|
919
|
+
this.dispatchEvent(new FocusEvent('it-focus', { bubbles: true, composed: true }));
|
|
920
|
+
}
|
|
921
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
922
|
+
_handleClick(e) {
|
|
923
|
+
this.dispatchEvent(new MouseEvent('it-click', { bubbles: true, composed: true }));
|
|
924
|
+
}
|
|
925
|
+
/*
|
|
926
|
+
Override default browser validation messages
|
|
927
|
+
*/
|
|
928
|
+
handleValidationMessages() {
|
|
929
|
+
if (!this.customValidation) {
|
|
930
|
+
const _v = this.inputElement.validity;
|
|
931
|
+
const isRequiredHandledByGroup = this.isInGroup === true;
|
|
932
|
+
if (_v.valueMissing && !isRequiredHandledByGroup) {
|
|
933
|
+
this.setCustomValidity(this.$t('validityRequired'));
|
|
934
|
+
}
|
|
935
|
+
else if (_v.patternMismatch) {
|
|
936
|
+
this.setCustomValidity(this.$t('validityPattern'));
|
|
937
|
+
}
|
|
938
|
+
else if (_v.tooShort) {
|
|
939
|
+
this.setCustomValidity(this.$t('validityMinlength').replace('{minlength}', this.minlength.toString()));
|
|
940
|
+
}
|
|
941
|
+
else if (_v.tooLong) {
|
|
942
|
+
this.setCustomValidity(this.$t('validityMaxlength').replace('{maxlength}', this.maxlength.toString()));
|
|
943
|
+
}
|
|
944
|
+
else {
|
|
945
|
+
/* nothing. Usa il messaggio di errore della validazione
|
|
946
|
+
di default del browser per altri errori di validità come:
|
|
947
|
+
- typeMismatch
|
|
948
|
+
- rangeUnderflow
|
|
949
|
+
- rangeOverflow
|
|
950
|
+
- stepMismatch
|
|
951
|
+
- badInput */
|
|
952
|
+
const otherConstraintErrors = _v.typeMismatch || _v.rangeUnderflow || _v.rangeOverflow || _v.stepMismatch || _v.badInput;
|
|
953
|
+
if (!otherConstraintErrors) {
|
|
954
|
+
this.setCustomValidity('');
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
this.validationMessage = this.inputElement.validationMessage;
|
|
959
|
+
}
|
|
960
|
+
_handleInvalid(event) {
|
|
961
|
+
this.formControlController.setValidity(false);
|
|
962
|
+
this.formControlController.emitInvalidEvent(event);
|
|
963
|
+
}
|
|
964
|
+
_handleChange(e) {
|
|
965
|
+
const target = e.target;
|
|
966
|
+
let value;
|
|
967
|
+
if (target instanceof HTMLInputElement) {
|
|
968
|
+
switch (target.type) {
|
|
969
|
+
case 'checkbox':
|
|
970
|
+
case 'radio':
|
|
971
|
+
value = target.checked;
|
|
972
|
+
break;
|
|
973
|
+
case 'file':
|
|
974
|
+
value = target.files; // FileList
|
|
975
|
+
break;
|
|
976
|
+
default:
|
|
977
|
+
value = target.value;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
else if (target instanceof HTMLSelectElement) {
|
|
981
|
+
if (target.multiple) {
|
|
982
|
+
value = Array.from(target.selectedOptions).map((o) => o.value);
|
|
983
|
+
}
|
|
984
|
+
else {
|
|
985
|
+
value = target.value;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
else {
|
|
989
|
+
// textarea o altri input con value
|
|
990
|
+
value = target.value;
|
|
991
|
+
}
|
|
992
|
+
this.dispatchEvent(new CustomEvent('it-change', {
|
|
993
|
+
detail: { value, el: target },
|
|
994
|
+
bubbles: true,
|
|
995
|
+
composed: true,
|
|
996
|
+
}));
|
|
997
|
+
}
|
|
998
|
+
updated(changedProperties) {
|
|
999
|
+
super.updated?.(changedProperties);
|
|
1000
|
+
if (this.customValidation) {
|
|
1001
|
+
this.setCustomValidity(this.validationText ?? '');
|
|
1002
|
+
}
|
|
1003
|
+
else if (this.formControlController.userInteracted()) {
|
|
1004
|
+
this.formControlController.updateValidity();
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
__decorate([
|
|
1009
|
+
state(),
|
|
1010
|
+
__metadata("design:type", Object)
|
|
1011
|
+
], FormControl.prototype, "_touched", void 0);
|
|
1012
|
+
__decorate([
|
|
1013
|
+
query('.it-form__control'),
|
|
1014
|
+
__metadata("design:type", HTMLInputElement)
|
|
1015
|
+
], FormControl.prototype, "inputElement", void 0);
|
|
1016
|
+
__decorate([
|
|
1017
|
+
property({ type: String, reflect: true }) // from FormControl
|
|
1018
|
+
,
|
|
1019
|
+
__metadata("design:type", Object)
|
|
1020
|
+
], FormControl.prototype, "name", void 0);
|
|
1021
|
+
__decorate([
|
|
1022
|
+
property({ reflect: true }),
|
|
1023
|
+
__metadata("design:type", Object)
|
|
1024
|
+
], FormControl.prototype, "value", void 0);
|
|
1025
|
+
__decorate([
|
|
1026
|
+
property({ type: Boolean, reflect: true }) // from FormControl
|
|
1027
|
+
,
|
|
1028
|
+
__metadata("design:type", Object)
|
|
1029
|
+
], FormControl.prototype, "disabled", void 0);
|
|
1030
|
+
__decorate([
|
|
1031
|
+
property({ reflect: true, type: String }),
|
|
1032
|
+
__metadata("design:type", Object)
|
|
1033
|
+
], FormControl.prototype, "form", void 0);
|
|
1034
|
+
__decorate([
|
|
1035
|
+
property({ type: Boolean, reflect: true, attribute: 'custom-validation' }),
|
|
1036
|
+
__metadata("design:type", Object)
|
|
1037
|
+
], FormControl.prototype, "customValidation", void 0);
|
|
1038
|
+
__decorate([
|
|
1039
|
+
property({ attribute: 'validity-message', reflect: true }),
|
|
1040
|
+
__metadata("design:type", String)
|
|
1041
|
+
], FormControl.prototype, "validationText", void 0);
|
|
1042
|
+
__decorate([
|
|
1043
|
+
property(),
|
|
1044
|
+
__metadata("design:type", String)
|
|
1045
|
+
], FormControl.prototype, "pattern", void 0);
|
|
1046
|
+
__decorate([
|
|
1047
|
+
property(),
|
|
1048
|
+
__metadata("design:type", Object)
|
|
1049
|
+
], FormControl.prototype, "min", void 0);
|
|
1050
|
+
__decorate([
|
|
1051
|
+
property(),
|
|
1052
|
+
__metadata("design:type", Object)
|
|
1053
|
+
], FormControl.prototype, "max", void 0);
|
|
1054
|
+
__decorate([
|
|
1055
|
+
property(),
|
|
1056
|
+
__metadata("design:type", Object)
|
|
1057
|
+
], FormControl.prototype, "step", void 0);
|
|
1058
|
+
__decorate([
|
|
1059
|
+
property({ type: Number }),
|
|
1060
|
+
__metadata("design:type", Object)
|
|
1061
|
+
], FormControl.prototype, "minlength", void 0);
|
|
1062
|
+
__decorate([
|
|
1063
|
+
property({ type: Number }),
|
|
1064
|
+
__metadata("design:type", Object)
|
|
1065
|
+
], FormControl.prototype, "maxlength", void 0);
|
|
1066
|
+
__decorate([
|
|
1067
|
+
property({ type: Boolean, reflect: true }) // from FormControl
|
|
1068
|
+
,
|
|
1069
|
+
__metadata("design:type", Object)
|
|
1070
|
+
], FormControl.prototype, "required", void 0);
|
|
1071
|
+
__decorate([
|
|
1072
|
+
property({ type: Boolean }),
|
|
1073
|
+
__metadata("design:type", Object)
|
|
1074
|
+
], FormControl.prototype, "isInGroup", void 0);
|
|
1075
|
+
__decorate([
|
|
1076
|
+
state(),
|
|
1077
|
+
__metadata("design:type", Object)
|
|
1078
|
+
], FormControl.prototype, "validationMessage", void 0);
|
|
1079
|
+
|
|
1080
|
+
if (typeof window !== 'undefined') {
|
|
1081
|
+
window._itAnalytics = window._itAnalytics || {};
|
|
1082
|
+
window._itAnalytics = {
|
|
1083
|
+
...window._itAnalytics,
|
|
1084
|
+
version: '1.0.0-alpha.4',
|
|
1085
|
+
};
|
|
605
1086
|
}
|
|
606
|
-
const BaseLocalizedComponent = LocalizeMixin(BaseComponent);
|
|
607
1087
|
|
|
608
1088
|
/**
|
|
609
1089
|
* Checks for repetition of characters in
|
|
@@ -778,11 +1258,8 @@ const translation = {
|
|
|
778
1258
|
passwordSuggestionFollowedPlural: 'suggerimenti seguiti',
|
|
779
1259
|
passwordSuggestionOf: 'di',
|
|
780
1260
|
passwordSuggestionMetLabel: 'Soddisfatto:',
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
validityPattern: 'Il valore non corrisponde al formato richiesto.',
|
|
784
|
-
validityMinlength: 'Il valore deve essere lungo almeno {minlength} caratteri.',
|
|
785
|
-
validityMaxlength: 'Il valore deve essere lungo al massimo {maxlength} caratteri.',
|
|
1261
|
+
increaseValue: 'Aumenta il valore',
|
|
1262
|
+
decreaseValue: 'Diminuisci il valore',
|
|
786
1263
|
};
|
|
787
1264
|
|
|
788
1265
|
var styles = css`@charset "UTF-8";
|
|
@@ -911,14 +1388,8 @@ a {
|
|
|
911
1388
|
text-decoration-skip-ink: auto;
|
|
912
1389
|
text-underline-offset: 2px;
|
|
913
1390
|
}
|
|
914
|
-
a:hover
|
|
1391
|
+
a:hover {
|
|
915
1392
|
color: var(--bs-color-link-hover);
|
|
916
|
-
text-decoration: underline;
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
|
920
|
-
color: inherit;
|
|
921
|
-
text-decoration: none;
|
|
922
1393
|
}
|
|
923
1394
|
|
|
924
1395
|
pre,
|
|
@@ -1051,23 +1522,6 @@ fieldset {
|
|
|
1051
1522
|
border: 0;
|
|
1052
1523
|
}
|
|
1053
1524
|
|
|
1054
|
-
legend {
|
|
1055
|
-
float: left;
|
|
1056
|
-
width: 100%;
|
|
1057
|
-
padding: 0;
|
|
1058
|
-
margin-bottom: 0.5rem;
|
|
1059
|
-
font-size: calc(1.275rem + 0.3vw);
|
|
1060
|
-
line-height: inherit;
|
|
1061
|
-
}
|
|
1062
|
-
@media (min-width: 1200px) {
|
|
1063
|
-
legend {
|
|
1064
|
-
font-size: 1.5rem;
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
legend + * {
|
|
1068
|
-
clear: left;
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
1525
|
::-webkit-datetime-edit-fields-wrapper,
|
|
1072
1526
|
::-webkit-datetime-edit-text,
|
|
1073
1527
|
::-webkit-datetime-edit-minute,
|
|
@@ -1179,6 +1633,9 @@ progress {
|
|
|
1179
1633
|
transition: all var(--bs-transition-instant) ease-in-out;
|
|
1180
1634
|
user-select: none;
|
|
1181
1635
|
}
|
|
1636
|
+
.btn:hover {
|
|
1637
|
+
color: var(--bs-btn-text-color);
|
|
1638
|
+
}
|
|
1182
1639
|
.btn:disabled, .btn.disabled {
|
|
1183
1640
|
opacity: var(--bs-btn-disabled-opacity);
|
|
1184
1641
|
cursor: not-allowed;
|
|
@@ -1417,13 +1874,51 @@ a.btn-outline-danger:active {
|
|
|
1417
1874
|
.bg-dark .btn-link {
|
|
1418
1875
|
--bs-btn-text-color: var(--bs-color-text-inverse);
|
|
1419
1876
|
}
|
|
1877
|
+
.bg-dark a.btn-primary,
|
|
1878
|
+
.bg-dark .btn-primary {
|
|
1879
|
+
--bs-btn-text-color: var(--bs-color-text-primary);
|
|
1880
|
+
--bs-btn-background: var(--bs-color-background-inverse);
|
|
1881
|
+
}
|
|
1882
|
+
.bg-dark a.btn-primary:hover,
|
|
1883
|
+
.bg-dark .btn-primary:hover {
|
|
1884
|
+
--bs-btn-background: color-mix(in srgb, var(--bs-color-background-inverse) 85%, black);
|
|
1885
|
+
}
|
|
1886
|
+
.bg-dark a.btn-primary:active,
|
|
1887
|
+
.bg-dark .btn-primary:active {
|
|
1888
|
+
--bs-btn-background: color-mix(in srgb, var(--bs-color-background-inverse) 80%, black);
|
|
1889
|
+
}
|
|
1890
|
+
.bg-dark a.btn-secondary,
|
|
1891
|
+
.bg-dark .btn-secondary {
|
|
1892
|
+
--bs-btn-text-color: var(--bs-color-text-inverse);
|
|
1893
|
+
--bs-btn-background: var(--bs-color-background-secondary);
|
|
1894
|
+
}
|
|
1895
|
+
.bg-dark a.btn-secondary:hover, .bg-dark a.btn-secondary:active,
|
|
1896
|
+
.bg-dark .btn-secondary:hover,
|
|
1897
|
+
.bg-dark .btn-secondary:active {
|
|
1898
|
+
--bs-btn-background: color-mix(in srgb, var(--bs-color-background-secondary) 85%, black);
|
|
1899
|
+
}
|
|
1420
1900
|
.bg-dark .btn-outline-primary,
|
|
1421
|
-
.bg-dark a.btn-outline-primary
|
|
1901
|
+
.bg-dark a.btn-outline-primary {
|
|
1902
|
+
--bs-btn-outline-border-color: var(--bs-color-border-inverse);
|
|
1903
|
+
--bs-btn-text-color: var(--bs-color-text-inverse);
|
|
1904
|
+
}
|
|
1905
|
+
.bg-dark .btn-outline-primary:hover,
|
|
1906
|
+
.bg-dark a.btn-outline-primary:hover {
|
|
1907
|
+
--bs-btn-boxshadow-color-darken: color-mix(in srgb, var(--bs-color-border-inverse) 80%, black);
|
|
1908
|
+
--bs-btn-boxshadow-color-desaturated: color-mix(in srgb, var(--bs-btn-boxshadow-color-darken) 80%, gray);
|
|
1909
|
+
--bs-btn-outline-border-color: var(--bs-btn-boxshadow-color-desaturated);
|
|
1910
|
+
}
|
|
1422
1911
|
.bg-dark .btn-outline-secondary,
|
|
1423
1912
|
.bg-dark a.btn-outline-secondary {
|
|
1424
|
-
--bs-btn-outline-border-color: var(--bs-color-border-inverse);
|
|
1425
1913
|
--bs-btn-text-color: var(--bs-color-text-inverse);
|
|
1426
1914
|
}
|
|
1915
|
+
.bg-dark .btn-outline-secondary:hover, .bg-dark .btn-outline-secondary:active,
|
|
1916
|
+
.bg-dark a.btn-outline-secondary:hover,
|
|
1917
|
+
.bg-dark a.btn-outline-secondary:active {
|
|
1918
|
+
--bs-btn-boxshadow-color-darken: color-mix(in srgb, var(--bs-color-background-secondary) 80%, black);
|
|
1919
|
+
--bs-btn-boxshadow-color-desaturated: color-mix(in srgb, var(--bs-btn-boxshadow-color-darken) 80%, gray);
|
|
1920
|
+
--bs-btn-outline-border-color: var(--bs-btn-boxshadow-color-desaturated);
|
|
1921
|
+
}
|
|
1427
1922
|
|
|
1428
1923
|
.btn-close {
|
|
1429
1924
|
position: relative;
|
|
@@ -3208,8 +3703,8 @@ blockquote.blockquote-card.dark .blockquote-footer,
|
|
|
3208
3703
|
--bs-form-control-border-color: var(--bs-color-border-secondary);
|
|
3209
3704
|
--bs-form-control-border-radius: var(--bs-radius-smooth);
|
|
3210
3705
|
--bs-form-control-placeholder-color: var(--bs-color-text-muted);
|
|
3211
|
-
--bs-form-control-label-color: var(--bs-color-text-
|
|
3212
|
-
--bs-form-control-text-color: var(--bs-color-text-
|
|
3706
|
+
--bs-form-control-label-color: var(--bs-color-text-base);
|
|
3707
|
+
--bs-form-control-text-color: var(--bs-color-text-secondary);
|
|
3213
3708
|
--bs-form-control-font-size: var(--bs-body-font-size);
|
|
3214
3709
|
--bs-form-group-spacing-y: var(--bs-spacing-m);
|
|
3215
3710
|
--bs-form-checkbox-border-color: var(--bs-color-border-secondary);
|
|
@@ -3353,20 +3848,12 @@ input[type=time] {
|
|
|
3353
3848
|
}
|
|
3354
3849
|
|
|
3355
3850
|
fieldset legend {
|
|
3356
|
-
|
|
3357
|
-
display: block;
|
|
3358
|
-
width: auto;
|
|
3359
|
-
max-width: 100%;
|
|
3360
|
-
margin-bottom: 0;
|
|
3851
|
+
margin-bottom: var(--bs-spacing-s);
|
|
3361
3852
|
padding: 0 var(--bs-form-input-spacing-x);
|
|
3362
|
-
float: none;
|
|
3363
3853
|
background-color: transparent;
|
|
3364
|
-
color: var(--bs-form-
|
|
3365
|
-
font-size:
|
|
3366
|
-
font-weight:
|
|
3367
|
-
line-height: calc(2.5rem - 1px);
|
|
3368
|
-
transition: 0.2s ease-out;
|
|
3369
|
-
cursor: text;
|
|
3854
|
+
color: var(--bs-form-control-text-color);
|
|
3855
|
+
font-size: var(--bs-label-sm);
|
|
3856
|
+
font-weight: var(--bs-font-weight-solid);
|
|
3370
3857
|
}
|
|
3371
3858
|
|
|
3372
3859
|
::placeholder {
|
|
@@ -3432,8 +3919,8 @@ input::-webkit-datetime-edit {
|
|
|
3432
3919
|
|
|
3433
3920
|
.form-check {
|
|
3434
3921
|
position: relative;
|
|
3435
|
-
margin-bottom: var(--bs-spacing-s);
|
|
3436
3922
|
padding-left: 0;
|
|
3923
|
+
align-items: center;
|
|
3437
3924
|
}
|
|
3438
3925
|
.form-check + .form-check {
|
|
3439
3926
|
margin-top: var(--bs-spacing-s);
|
|
@@ -3451,11 +3938,11 @@ input::-webkit-datetime-edit {
|
|
|
3451
3938
|
position: relative;
|
|
3452
3939
|
display: flex;
|
|
3453
3940
|
align-items: center;
|
|
3454
|
-
padding-left:
|
|
3941
|
+
padding-left: 28px;
|
|
3455
3942
|
font-size: var(--bs-label-font-size);
|
|
3456
3943
|
font-weight: var(--bs-font-weight-solid);
|
|
3457
|
-
line-height: 1;
|
|
3458
3944
|
cursor: pointer;
|
|
3945
|
+
margin-bottom: 0;
|
|
3459
3946
|
user-select: none;
|
|
3460
3947
|
}
|
|
3461
3948
|
@media (min-width: 576px) {
|
|
@@ -3536,7 +4023,7 @@ input::-webkit-datetime-edit {
|
|
|
3536
4023
|
transition: all var(--bs-transition-instant) ease-out;
|
|
3537
4024
|
}
|
|
3538
4025
|
.form-check input[type=radio]:not(:checked) + label::after, .form-check input[type=radio]:not(:checked) + label::before {
|
|
3539
|
-
border-color: var(
|
|
4026
|
+
border-color: var(--bs-form-checkbox-border-color);
|
|
3540
4027
|
}
|
|
3541
4028
|
.form-check input[type=radio]:not(:checked) + label:after {
|
|
3542
4029
|
z-index: -1;
|
|
@@ -3614,6 +4101,13 @@ input::-webkit-datetime-edit {
|
|
|
3614
4101
|
background-color: var(--bs-form-checked-color);
|
|
3615
4102
|
}
|
|
3616
4103
|
|
|
4104
|
+
.form-check-inline {
|
|
4105
|
+
display: inline-block;
|
|
4106
|
+
}
|
|
4107
|
+
.form-check-inline:not(:last-child) {
|
|
4108
|
+
margin-right: var(--bs-spacing-m);
|
|
4109
|
+
}
|
|
4110
|
+
|
|
3617
4111
|
@media (prefers-reduced-motion: reduce) {
|
|
3618
4112
|
fieldset legend,
|
|
3619
4113
|
.form-group label,
|
|
@@ -3677,9 +4171,6 @@ input::-webkit-datetime-edit {
|
|
|
3677
4171
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23cc334d' viewBox='0 0 384 512'%3E%3Cpath d='M231.6 256l130.1-130.1c4.7-4.7 4.7-12.3 0-17l-22.6-22.6c-4.7-4.7-12.3-4.7-17 0L192 216.4 61.9 86.3c-4.7-4.7-12.3-4.7-17 0l-22.6 22.6c-4.7 4.7-4.7 12.3 0 17L152.4 256 22.3 386.1c-4.7 4.7-4.7 12.3 0 17l22.6 22.6c4.7 4.7 12.3 4.7 17 0L192 295.6l130.1 130.1c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17L231.6 256z'/%3E%3C/svg%3E");
|
|
3678
4172
|
border-color: var(--bs-color-border-danger);
|
|
3679
4173
|
}
|
|
3680
|
-
.was-validated .form-control:invalid[type=number], .form-control.is-invalid[type=number] {
|
|
3681
|
-
background-size: 80px 30%;
|
|
3682
|
-
}
|
|
3683
4174
|
.form-control.warning {
|
|
3684
4175
|
background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M2%2012C2%206.47715%206.47715%202%2012%202C14.6522%202%2017.1957%203.05357%2019.0711%204.92893C20.9464%206.8043%2022%209.34784%2022%2012C22%2017.5228%2017.5228%2022%2012%2022C6.47715%2022%202%2017.5228%202%2012ZM3%2012C3%2016.9706%207.02944%2021%2012%2021C16.9706%2021%2021%2016.9706%2021%2012C21%207.02944%2016.9706%203%2012%203C7.02944%203%203%207.02944%203%2012ZM11.5%2014.2V5.7H12.7V14.2H11.5ZM12.6%2018.3V16.5H11.4V18.3H12.6Z%22/%3E%0A%3C/svg%3E") no-repeat;
|
|
3685
4176
|
border-color: var(--bs-color-border-warning);
|
|
@@ -3771,6 +4262,106 @@ textarea.form-control-lg {
|
|
|
3771
4262
|
display: block;
|
|
3772
4263
|
}
|
|
3773
4264
|
|
|
4265
|
+
.input-number {
|
|
4266
|
+
position: relative;
|
|
4267
|
+
}
|
|
4268
|
+
.input-number.input-number-adaptive {
|
|
4269
|
+
width: fit-content;
|
|
4270
|
+
}
|
|
4271
|
+
.input-number.input-number-adaptive input[type=number] {
|
|
4272
|
+
width: auto;
|
|
4273
|
+
transition: all va(--bs-transition-instant);
|
|
4274
|
+
}
|
|
4275
|
+
.input-number input[type=number] {
|
|
4276
|
+
appearance: textfield;
|
|
4277
|
+
border-top-right-radius: var(--bs-form-control-border-radius) !important;
|
|
4278
|
+
border-bottom-right-radius: var(--bs-form-control-border-radius) !important;
|
|
4279
|
+
}
|
|
4280
|
+
.input-number input[type=number]::-webkit-inner-spin-button, .input-number input[type=number]::-webkit-outer-spin-button {
|
|
4281
|
+
-webkit-appearance: none;
|
|
4282
|
+
}
|
|
4283
|
+
.input-number input[type=number]::-ms-clear {
|
|
4284
|
+
display: none;
|
|
4285
|
+
}
|
|
4286
|
+
.input-number input[type=number]:not(:disabled) {
|
|
4287
|
+
border-left: 1px solid var(--bs-form-control-border-color);
|
|
4288
|
+
}
|
|
4289
|
+
.input-number input[type=number][readonly] ~ .input-group-text .input-number-add,
|
|
4290
|
+
.input-number input[type=number][readonly] ~ .input-group-text .input-number-sub {
|
|
4291
|
+
display: none;
|
|
4292
|
+
}
|
|
4293
|
+
.input-number.disabled button {
|
|
4294
|
+
display: none;
|
|
4295
|
+
pointer-events: none;
|
|
4296
|
+
}
|
|
4297
|
+
.input-number.disabled button:hover {
|
|
4298
|
+
cursor: not-allowed;
|
|
4299
|
+
}
|
|
4300
|
+
.input-number .input-group-text.align-buttons {
|
|
4301
|
+
position: absolute;
|
|
4302
|
+
top: 0;
|
|
4303
|
+
bottom: 0;
|
|
4304
|
+
right: 0;
|
|
4305
|
+
z-index: 10;
|
|
4306
|
+
padding-right: var(--bs-form-control-spacing);
|
|
4307
|
+
border: none;
|
|
4308
|
+
background: transparent;
|
|
4309
|
+
}
|
|
4310
|
+
.is-invalid + .input-number .input-group-text.align-buttons {
|
|
4311
|
+
bottom: 0;
|
|
4312
|
+
}
|
|
4313
|
+
.input-number .input-group-text button {
|
|
4314
|
+
position: relative;
|
|
4315
|
+
transition: opacity 0.1s;
|
|
4316
|
+
padding: 0;
|
|
4317
|
+
border: none;
|
|
4318
|
+
height: 50%;
|
|
4319
|
+
width: 16px;
|
|
4320
|
+
background: transparent;
|
|
4321
|
+
}
|
|
4322
|
+
.input-number .input-group-text button:after {
|
|
4323
|
+
position: absolute;
|
|
4324
|
+
top: 50%;
|
|
4325
|
+
left: 50%;
|
|
4326
|
+
transform: translateX(-50%) translateY(-50%);
|
|
4327
|
+
content: "";
|
|
4328
|
+
width: 0;
|
|
4329
|
+
height: 0;
|
|
4330
|
+
border-style: solid;
|
|
4331
|
+
}
|
|
4332
|
+
.input-number .input-group-text button:focus.input-number-add:after, .input-number .input-group-text button:hover.input-number-add:after {
|
|
4333
|
+
border-color: transparent transparent hsl(210, 54%, 20%) transparent;
|
|
4334
|
+
}
|
|
4335
|
+
.input-number .input-group-text button:focus.input-number-sub:after, .input-number .input-group-text button:hover.input-number-sub:after {
|
|
4336
|
+
border-color: hsl(210, 54%, 20%) transparent transparent transparent;
|
|
4337
|
+
}
|
|
4338
|
+
.input-number .input-group-text button:focus:not([data-focus-mouse=true]) {
|
|
4339
|
+
opacity: 1;
|
|
4340
|
+
}
|
|
4341
|
+
.input-number .input-group-text button.input-number-add:after {
|
|
4342
|
+
border-width: 0 5px 6px 5px;
|
|
4343
|
+
border-color: transparent transparent hsl(210, 17.6470588235%, 43.35%) transparent;
|
|
4344
|
+
}
|
|
4345
|
+
.input-number .input-group-text button.input-number-sub:after {
|
|
4346
|
+
border-width: 6px 5px 0 5px;
|
|
4347
|
+
border-color: hsl(210, 17.6470588235%, 43.35%) transparent transparent transparent;
|
|
4348
|
+
}
|
|
4349
|
+
.input-number .input-group-text button:hover {
|
|
4350
|
+
cursor: pointer;
|
|
4351
|
+
}
|
|
4352
|
+
|
|
4353
|
+
.input-number .input-group-text + input[type=number] {
|
|
4354
|
+
border-left: 0;
|
|
4355
|
+
}
|
|
4356
|
+
|
|
4357
|
+
@media (min-width: 1200px) {
|
|
4358
|
+
.input-number button {
|
|
4359
|
+
opacity: 0;
|
|
4360
|
+
}
|
|
4361
|
+
.input-number:hover button {
|
|
4362
|
+
opacity: 1;
|
|
4363
|
+
}
|
|
4364
|
+
}
|
|
3774
4365
|
.input-group {
|
|
3775
4366
|
position: relative;
|
|
3776
4367
|
display: flex;
|
|
@@ -3919,9 +4510,9 @@ textarea.just-validate-success-field {
|
|
|
3919
4510
|
border-bottom-width: 1px;
|
|
3920
4511
|
}
|
|
3921
4512
|
|
|
3922
|
-
input[type=checkbox].
|
|
3923
|
-
input[type=radio].
|
|
3924
|
-
color: var(--bs-color-
|
|
4513
|
+
input[type=checkbox].is-invalid,
|
|
4514
|
+
input[type=radio].is-invalid {
|
|
4515
|
+
--bs-form-checkbox-border-color: var(--bs-color-border-danger);
|
|
3925
4516
|
}
|
|
3926
4517
|
|
|
3927
4518
|
select.is-invalid {
|
|
@@ -4108,6 +4699,10 @@ select.just-validate-success-field {
|
|
|
4108
4699
|
display: none !important;
|
|
4109
4700
|
}
|
|
4110
4701
|
|
|
4702
|
+
.flex-column {
|
|
4703
|
+
flex-direction: column !important;
|
|
4704
|
+
}
|
|
4705
|
+
|
|
4111
4706
|
@media (min-width: 576px) {
|
|
4112
4707
|
.m-sm-0 {
|
|
4113
4708
|
margin: 0 !important;
|
|
@@ -4115,6 +4710,9 @@ select.just-validate-success-field {
|
|
|
4115
4710
|
.d-sm-none {
|
|
4116
4711
|
display: none !important;
|
|
4117
4712
|
}
|
|
4713
|
+
.flex-sm-column {
|
|
4714
|
+
flex-direction: column !important;
|
|
4715
|
+
}
|
|
4118
4716
|
}
|
|
4119
4717
|
@media (min-width: 768px) {
|
|
4120
4718
|
.m-md-0 {
|
|
@@ -4123,6 +4721,9 @@ select.just-validate-success-field {
|
|
|
4123
4721
|
.d-md-none {
|
|
4124
4722
|
display: none !important;
|
|
4125
4723
|
}
|
|
4724
|
+
.flex-md-column {
|
|
4725
|
+
flex-direction: column !important;
|
|
4726
|
+
}
|
|
4126
4727
|
}
|
|
4127
4728
|
@media (min-width: 992px) {
|
|
4128
4729
|
.m-lg-0 {
|
|
@@ -4131,6 +4732,9 @@ select.just-validate-success-field {
|
|
|
4131
4732
|
.d-lg-none {
|
|
4132
4733
|
display: none !important;
|
|
4133
4734
|
}
|
|
4735
|
+
.flex-lg-column {
|
|
4736
|
+
flex-direction: column !important;
|
|
4737
|
+
}
|
|
4134
4738
|
}
|
|
4135
4739
|
@media (min-width: 1200px) {
|
|
4136
4740
|
.m-xl-0 {
|
|
@@ -4139,6 +4743,9 @@ select.just-validate-success-field {
|
|
|
4139
4743
|
.d-xl-none {
|
|
4140
4744
|
display: none !important;
|
|
4141
4745
|
}
|
|
4746
|
+
.flex-xl-column {
|
|
4747
|
+
flex-direction: column !important;
|
|
4748
|
+
}
|
|
4142
4749
|
}
|
|
4143
4750
|
@media (min-width: 1400px) {
|
|
4144
4751
|
.m-xxl-0 {
|
|
@@ -4147,153 +4754,86 @@ select.just-validate-success-field {
|
|
|
4147
4754
|
.d-xxl-none {
|
|
4148
4755
|
display: none !important;
|
|
4149
4756
|
}
|
|
4757
|
+
.flex-xxl-column {
|
|
4758
|
+
flex-direction: column !important;
|
|
4759
|
+
}
|
|
4150
4760
|
}
|
|
4151
4761
|
@media print {
|
|
4152
4762
|
.d-print-none {
|
|
4153
4763
|
display: none !important;
|
|
4154
4764
|
}
|
|
4155
4765
|
}
|
|
4156
|
-
:host {
|
|
4157
|
-
display: block;
|
|
4158
|
-
}
|
|
4159
|
-
|
|
4160
4766
|
.password-icon {
|
|
4161
4767
|
top: calc(var(--bs-form-control-spacing) * 5);
|
|
4162
4768
|
--bs-icon-default: var(--bs-icon-primary);
|
|
4769
|
+
}
|
|
4770
|
+
|
|
4771
|
+
.is-invalid + .input-group-text.align-buttons {
|
|
4772
|
+
bottom: 0 !important;
|
|
4163
4773
|
}`;
|
|
4164
4774
|
|
|
4775
|
+
var ItInput_1;
|
|
4165
4776
|
registerTranslation(translation);
|
|
4166
|
-
let ItInput = class ItInput extends
|
|
4777
|
+
let ItInput = ItInput_1 = class ItInput extends FormControl {
|
|
4167
4778
|
constructor() {
|
|
4168
4779
|
super(...arguments);
|
|
4169
|
-
this.
|
|
4170
|
-
this.
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
this.label = '';
|
|
4176
|
-
this.labelHidden = false;
|
|
4780
|
+
this._slotPrepend = null;
|
|
4781
|
+
this._slotAppend = null;
|
|
4782
|
+
/**
|
|
4783
|
+
* The type of input. Works the same as a native `<input>` element, but only a subset of types are supported. Defaults
|
|
4784
|
+
* to `text`.
|
|
4785
|
+
*/
|
|
4177
4786
|
this.type = 'text';
|
|
4178
|
-
|
|
4787
|
+
/** If you want number-input to be adaptive in width */
|
|
4788
|
+
this.adaptive = false;
|
|
4789
|
+
/** If you want label to be hidden. */
|
|
4790
|
+
this.labelHidden = false;
|
|
4791
|
+
/** Placeholder text to show as a hint when the input is empty. */
|
|
4179
4792
|
this.placeholder = '';
|
|
4793
|
+
/** The input's help text. */
|
|
4180
4794
|
this.supportText = '';
|
|
4181
|
-
|
|
4795
|
+
/** If you want the input to be displayed as plaintext. */
|
|
4182
4796
|
this.plaintext = false;
|
|
4797
|
+
/** If the input is read-only. */
|
|
4183
4798
|
this.readonly = false;
|
|
4799
|
+
/** If your input is of type 'password' and you want to display a strength meter */
|
|
4184
4800
|
this.passwordStrengthMeter = false;
|
|
4801
|
+
/** If your input is of type 'password' and you want to show password suggestions. */
|
|
4185
4802
|
this.suggestions = false;
|
|
4186
|
-
this.minlength = -1;
|
|
4187
|
-
this.maxlength = -1;
|
|
4188
4803
|
this._passwordVisible = false;
|
|
4189
4804
|
this._strengthInfos = '';
|
|
4190
4805
|
this._score = 0;
|
|
4191
|
-
this._value = ''; // from validity mixin
|
|
4192
|
-
this._touched = false; // from validity mixin
|
|
4193
|
-
this.validityMessage = ''; // from validity mixin
|
|
4194
|
-
}
|
|
4195
|
-
static get formAssociated() {
|
|
4196
|
-
return true;
|
|
4197
|
-
}
|
|
4198
|
-
get value() {
|
|
4199
|
-
if (this._inputElement) {
|
|
4200
|
-
return this._inputElement.value;
|
|
4201
|
-
}
|
|
4202
|
-
return this._value;
|
|
4203
|
-
}
|
|
4204
|
-
set value(value) {
|
|
4205
|
-
const oldValue = this._value;
|
|
4206
|
-
this._value = value;
|
|
4207
|
-
this.internals.setFormValue(value); // <- Associa il valore al form
|
|
4208
|
-
// make sure that lit-element updates the right properties
|
|
4209
|
-
this.requestUpdate('value', oldValue);
|
|
4210
|
-
// we set the value directly on the input (when available)
|
|
4211
|
-
// so that programatic manipulation updates the UI correctly
|
|
4212
|
-
if (this._inputElement && this._inputElement.value !== value) {
|
|
4213
|
-
this._inputElement.value = value;
|
|
4214
|
-
}
|
|
4215
|
-
}
|
|
4216
|
-
// Getter pubblico per accedere all'input
|
|
4217
|
-
get inputElement() {
|
|
4218
|
-
return this.shadowRoot?.querySelector('input');
|
|
4219
|
-
}
|
|
4220
|
-
_handleFormdata(event) {
|
|
4221
|
-
// Add name and value to the form's submission data if it's not disabled.
|
|
4222
|
-
if (!this.disabled) {
|
|
4223
|
-
const { formData } = event;
|
|
4224
|
-
formData.append(this.name, this._value);
|
|
4225
|
-
}
|
|
4226
|
-
}
|
|
4227
|
-
_handleInput(e) {
|
|
4228
|
-
const input = e.target;
|
|
4229
|
-
this.value = input.value;
|
|
4230
|
-
if (this.passwordStrengthMeter) {
|
|
4231
|
-
this._checkPasswordStrength(input.value);
|
|
4232
|
-
}
|
|
4233
|
-
this.dispatchEvent(new CustomEvent('on-input', {
|
|
4234
|
-
detail: { value: input.value, el: input },
|
|
4235
|
-
bubbles: true,
|
|
4236
|
-
composed: true,
|
|
4237
|
-
}));
|
|
4238
4806
|
}
|
|
4239
|
-
|
|
4240
|
-
if (
|
|
4241
|
-
|
|
4242
|
-
this._checkValidity({
|
|
4243
|
-
[VALIDATION_STATUS.INVALID]: this.$t('validityInvalid'),
|
|
4244
|
-
[VALIDATION_STATUS.ERROR_REQUIRED]: this.$t('validityRequired'),
|
|
4245
|
-
[VALIDATION_STATUS.PATTERN]: this.$t('validityPattern'),
|
|
4246
|
-
[VALIDATION_STATUS.MINLENGTH]: this.$t('validityMinlength'),
|
|
4247
|
-
[VALIDATION_STATUS.MAXLENGTH]: this.$t('validityMaxlength'),
|
|
4248
|
-
}, inputValid);
|
|
4807
|
+
get label() {
|
|
4808
|
+
if (this.labelElements.length > 0) {
|
|
4809
|
+
return this.labelElements[0].innerText.trim();
|
|
4249
4810
|
}
|
|
4811
|
+
return '';
|
|
4250
4812
|
}
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
this.checkValidity();
|
|
4813
|
+
get slotted() {
|
|
4814
|
+
return this._slotPrepend || this._slotAppend;
|
|
4254
4815
|
}
|
|
4255
4816
|
firstUpdated() {
|
|
4256
|
-
// this.addFocus(this.
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4817
|
+
// this.addFocus(this.inputElement); //NON serve per il momento perche sfruttiamo :focus-visible. Per gli input focus-visible si attiva anche al click perchè è il browser che lo gestisce
|
|
4818
|
+
this._slotPrepend = this.querySelector('[slot="prepend"]');
|
|
4819
|
+
this._slotAppend = this.querySelector('[slot="append"]');
|
|
4820
|
+
this._slotPrepend?.addEventListener('slotchange', () => {
|
|
4260
4821
|
this.requestUpdate();
|
|
4261
4822
|
});
|
|
4262
|
-
|
|
4823
|
+
this._slotAppend?.addEventListener('slotchange', () => {
|
|
4263
4824
|
this.requestUpdate();
|
|
4264
4825
|
});
|
|
4265
4826
|
}
|
|
4266
4827
|
connectedCallback() {
|
|
4267
4828
|
super.connectedCallback?.();
|
|
4268
|
-
/* così quando si scrive <it-input value="ciao"></it-input>, this.value viene impostato con 'ciao' */
|
|
4269
|
-
const attrValue = this.getAttribute('value');
|
|
4270
|
-
if (attrValue !== null) {
|
|
4271
|
-
this.value = attrValue;
|
|
4272
|
-
}
|
|
4273
4829
|
if (this.type === 'password' && this.minlength < 0) {
|
|
4274
4830
|
this.minlength = 8; // set default minlength for password
|
|
4275
4831
|
}
|
|
4276
|
-
|
|
4277
|
-
this.dispatchEvent(new CustomEvent('input-ready', { bubbles: true, detail: { el: this.inputElement } }));
|
|
4278
|
-
});
|
|
4832
|
+
this._handleReady();
|
|
4279
4833
|
}
|
|
4280
|
-
// protected override update(changedProperties: Map<string | number | symbol, unknown>): void {
|
|
4281
|
-
// if (changedProperties.has('value') || (changedProperties.has('required') && this.required)) {
|
|
4282
|
-
// this.updateComplete.then(() => {
|
|
4283
|
-
// this.checkValidity();
|
|
4284
|
-
// });
|
|
4285
|
-
// }
|
|
4286
|
-
// super.update(changedProperties);
|
|
4287
|
-
// }
|
|
4288
4834
|
updated(changedProperties) {
|
|
4289
4835
|
super.updated?.(changedProperties);
|
|
4290
|
-
|
|
4291
|
-
this.setCustomValidity(this.validationText);
|
|
4292
|
-
}
|
|
4293
|
-
if (this.invalid) {
|
|
4294
|
-
const message = this.validationText?.length > 0 ? this.validationText : (this.validityMessage ?? 'Campo non valido');
|
|
4295
|
-
this.internals.setValidity({ customError: this.invalid }, message);
|
|
4296
|
-
}
|
|
4836
|
+
// logger
|
|
4297
4837
|
if (this.passwordStrengthMeter && this.type !== 'password') {
|
|
4298
4838
|
this.logger.warn("The strength-meter property is enabled, but type isn't password. Please, remove strength-meter property.");
|
|
4299
4839
|
}
|
|
@@ -4301,13 +4841,24 @@ let ItInput = class ItInput extends ValidityMixin(FormMixin(BaseLocalizedCompone
|
|
|
4301
4841
|
this.logger.warn("The suggestions property is enabled, but type isn't password. Please, remove suggestions this property.");
|
|
4302
4842
|
}
|
|
4303
4843
|
if (!this.label || this.label?.length === 0) {
|
|
4304
|
-
this.logger.warn(`Label is required to ensure accessibility. Please, define a label for <it-input name="${this.name}" ... /> . Set attribute label-hidden="true" if you don't want to show label.`);
|
|
4844
|
+
this.logger.warn(`Label is required to ensure accessibility. Please, define a label for <it-input name="${this.name}" id="${this.id}" ... /> . Set attribute label-hidden="true" if you don't want to show label.`);
|
|
4845
|
+
}
|
|
4846
|
+
}
|
|
4847
|
+
_handleInput(e) {
|
|
4848
|
+
this.value = this.inputElement.value;
|
|
4849
|
+
if (this.value === '00') {
|
|
4850
|
+
this.value = '0';
|
|
4851
|
+
this.inputElement.value = '0';
|
|
4852
|
+
}
|
|
4853
|
+
if (this.passwordStrengthMeter) {
|
|
4854
|
+
this._checkPasswordStrength(this.inputElement.value);
|
|
4305
4855
|
}
|
|
4856
|
+
super._handleInput(e);
|
|
4306
4857
|
}
|
|
4307
4858
|
_togglePasswordVisibility() {
|
|
4308
4859
|
this._passwordVisible = !this._passwordVisible;
|
|
4309
|
-
if (this.
|
|
4310
|
-
this.
|
|
4860
|
+
if (this.inputElement) {
|
|
4861
|
+
this.inputElement.type = this._passwordVisible ? 'text' : 'password';
|
|
4311
4862
|
}
|
|
4312
4863
|
}
|
|
4313
4864
|
_checkPasswordStrength(value) {
|
|
@@ -4348,6 +4899,28 @@ let ItInput = class ItInput extends ValidityMixin(FormMixin(BaseLocalizedCompone
|
|
|
4348
4899
|
}
|
|
4349
4900
|
this._strengthInfos = text;
|
|
4350
4901
|
}
|
|
4902
|
+
static _cleanFloat(num) {
|
|
4903
|
+
return parseFloat(num.toPrecision(15));
|
|
4904
|
+
}
|
|
4905
|
+
_inputNumberIncDec(v) {
|
|
4906
|
+
const step = typeof this.step === 'number' ? this.step : Number(this.step) || 1;
|
|
4907
|
+
const value = typeof this.value === 'number' ? this.value : Number(this.value) || 0;
|
|
4908
|
+
const min = typeof this.min === 'number' ? this.min : Number(this.min);
|
|
4909
|
+
const max = typeof this.max === 'number' ? this.max : Number(this.max);
|
|
4910
|
+
const _v = v * step;
|
|
4911
|
+
const newValue = ItInput_1._cleanFloat(value + _v);
|
|
4912
|
+
if (newValue > max || newValue < min) ;
|
|
4913
|
+
else {
|
|
4914
|
+
const _value = newValue.toString();
|
|
4915
|
+
this.value = _value;
|
|
4916
|
+
this.inputElement.dispatchEvent(new Event('blur', { bubbles: true }));
|
|
4917
|
+
this.inputElement.dispatchEvent(new Event('change', { bubbles: true }));
|
|
4918
|
+
const liveRegion = this.shadowRoot?.querySelector(`#${this._id}-live-region`);
|
|
4919
|
+
if (liveRegion) {
|
|
4920
|
+
liveRegion.textContent = `${_value}`;
|
|
4921
|
+
}
|
|
4922
|
+
}
|
|
4923
|
+
}
|
|
4351
4924
|
_renderTogglePasswordButton() {
|
|
4352
4925
|
// Solo se type=password
|
|
4353
4926
|
if (this.type === 'password') {
|
|
@@ -4400,7 +4973,7 @@ let ItInput = class ItInput extends ValidityMixin(FormMixin(BaseLocalizedCompone
|
|
|
4400
4973
|
_renderpasswordStrengthMeter() {
|
|
4401
4974
|
if (this.type === 'password' && this.passwordStrengthMeter) {
|
|
4402
4975
|
const perc = this._score < 0 ? 0 : this._score;
|
|
4403
|
-
const color = this.
|
|
4976
|
+
const color = this.value?.length === 0 ? 'muted' : scoreColor(this._score);
|
|
4404
4977
|
return html `<div class="password-strength-meter">
|
|
4405
4978
|
${this._renderSuggestions()}
|
|
4406
4979
|
|
|
@@ -4433,9 +5006,9 @@ let ItInput = class ItInput extends ValidityMixin(FormMixin(BaseLocalizedCompone
|
|
|
4433
5006
|
}
|
|
4434
5007
|
return nothing;
|
|
4435
5008
|
}
|
|
4436
|
-
_renderInput(supportTextId) {
|
|
4437
|
-
const ariaDescribedBy = this.composeClass(this.supportText?.length > 0 ? supportTextId : '', this.passwordStrengthMeter ? `strengthMeterInfo_${this._id}` : '', this._ariaAttributes['aria-describedby']?.length > 0 ? this._ariaAttributes['aria-describedby'] : '',
|
|
4438
|
-
const inputClasses = this.composeClass(this.plaintext ? 'form-control-plaintext' : 'form-control', this.size ? `form-control-${this.size}` : '',
|
|
5009
|
+
_renderInput(supportTextId, invalid, validityMessage, showValidation) {
|
|
5010
|
+
const ariaDescribedBy = this.composeClass(this.supportText?.length > 0 ? supportTextId : '', this.passwordStrengthMeter ? `strengthMeterInfo_${this._id}` : '', this._ariaAttributes['aria-describedby']?.length > 0 ? this._ariaAttributes['aria-describedby'] : '', showValidation && validityMessage?.length > 0 ? `invalid-feedback-${this._id}` : '');
|
|
5011
|
+
const inputClasses = this.composeClass('it-form__control', this.plaintext ? 'form-control-plaintext' : 'form-control', this.size ? `form-control-${this.size}` : '', showValidation && invalid ? 'is-invalid' : '', showValidation && !invalid && !this.readonly ? 'just-validate-success-field' : '');
|
|
4439
5012
|
let inputRender;
|
|
4440
5013
|
if (this.type === 'textarea') {
|
|
4441
5014
|
inputRender = html `
|
|
@@ -4443,139 +5016,151 @@ let ItInput = class ItInput extends ValidityMixin(FormMixin(BaseLocalizedCompone
|
|
|
4443
5016
|
part="textarea focusable"
|
|
4444
5017
|
${setAttributes(this._ariaAttributes)}
|
|
4445
5018
|
aria-describedby=${ifDefined(ariaDescribedBy || undefined)}
|
|
4446
|
-
|
|
5019
|
+
aria-invalid=${ifDefined(invalid ? 'true' : undefined)}
|
|
4447
5020
|
@input="${this._handleInput}"
|
|
4448
5021
|
@blur=${this._handleBlur}
|
|
4449
5022
|
@focus=${this._handleFocus}
|
|
4450
5023
|
@click=${this._handleClick}
|
|
4451
5024
|
@change=${this._handleChange}
|
|
5025
|
+
@invalid=${this._handleInvalid}
|
|
4452
5026
|
id="${this._id}"
|
|
4453
5027
|
name="${this.name}"
|
|
4454
5028
|
?disabled=${this.disabled}
|
|
4455
5029
|
?readonly=${this.readonly}
|
|
4456
5030
|
?required=${this.required}
|
|
4457
|
-
|
|
5031
|
+
minlength=${ifDefined(this.minlength)}
|
|
5032
|
+
maxlength=${ifDefined(this.maxlength)}
|
|
5033
|
+
pattern=${ifDefined(this.pattern)}
|
|
5034
|
+
?formNoValidate=${this.customValidation}
|
|
5035
|
+
.value="${live(this.value)}"
|
|
4458
5036
|
placeholder=${ifDefined(this.placeholder || undefined)}
|
|
4459
5037
|
class="${inputClasses}"
|
|
4460
5038
|
></textarea>
|
|
4461
5039
|
`;
|
|
4462
5040
|
}
|
|
4463
5041
|
else {
|
|
5042
|
+
let style = null;
|
|
5043
|
+
if (this.type === 'number' && this.adaptive) {
|
|
5044
|
+
style = `width: calc(${this.value.toString().length}ch + 70px);`;
|
|
5045
|
+
}
|
|
4464
5046
|
inputRender = html `
|
|
4465
5047
|
<input
|
|
4466
5048
|
part="input focusable"
|
|
4467
5049
|
${setAttributes(this._ariaAttributes)}
|
|
4468
5050
|
aria-describedby=${ifDefined(ariaDescribedBy || undefined)}
|
|
4469
|
-
|
|
5051
|
+
aria-invalid=${ifDefined(invalid ? 'true' : undefined)}
|
|
4470
5052
|
@input="${this._handleInput}"
|
|
4471
5053
|
@blur=${this._handleBlur}
|
|
4472
5054
|
@focus=${this._handleFocus}
|
|
4473
5055
|
@click=${this._handleClick}
|
|
4474
5056
|
@change=${this._handleChange}
|
|
5057
|
+
@invalid=${this._handleInvalid}
|
|
4475
5058
|
type="${this.type}"
|
|
4476
5059
|
id="${this._id}"
|
|
4477
5060
|
name="${this.name}"
|
|
4478
5061
|
?disabled=${this.disabled}
|
|
4479
5062
|
?readonly=${this.readonly}
|
|
4480
5063
|
?required=${this.required}
|
|
4481
|
-
|
|
5064
|
+
minlength=${ifDefined(this.minlength)}
|
|
5065
|
+
maxlength=${ifDefined(this.maxlength)}
|
|
5066
|
+
min=${ifDefined(this.min)}
|
|
5067
|
+
max=${ifDefined(this.max)}
|
|
5068
|
+
step=${ifDefined(this.step)}
|
|
5069
|
+
autocomplete="off"
|
|
5070
|
+
pattern=${ifDefined(this.pattern)}
|
|
5071
|
+
?formNoValidate=${this.customValidation}
|
|
5072
|
+
.value="${live(this.value)}"
|
|
4482
5073
|
placeholder=${ifDefined(this.placeholder || undefined)}
|
|
4483
5074
|
class="${inputClasses}"
|
|
5075
|
+
style=${ifDefined(style)}
|
|
4484
5076
|
/>${this._renderTogglePasswordButton()}
|
|
4485
5077
|
`;
|
|
4486
5078
|
}
|
|
4487
|
-
inputRender = html `
|
|
4488
|
-
${inputRender}
|
|
4489
|
-
<div
|
|
4490
|
-
role="alert"
|
|
4491
|
-
id="invalid-feedback-${this._id}"
|
|
4492
|
-
class="invalid-feedback form-feedback form-text form-feedback just-validate-error-label"
|
|
4493
|
-
?hidden=${!(this.validityMessage?.length > 0)}
|
|
4494
|
-
>
|
|
4495
|
-
<span class="visually-hidden">${this.label}: </span>${this.validityMessage}
|
|
4496
|
-
</div>
|
|
4497
|
-
`;
|
|
4498
5079
|
return inputRender;
|
|
4499
5080
|
}
|
|
4500
5081
|
// Render the UI as a function of component state
|
|
4501
5082
|
render() {
|
|
4502
5083
|
const supportTextId = `${this._id}-support-text`;
|
|
4503
5084
|
const supportTextRender = html ` ${when(this.supportText, () => html ` <small class="form-text" id="${supportTextId}">${this.supportText}</small> `)}`;
|
|
5085
|
+
const showValidation = this.formControlController.submittedOnce || this.customValidation; // true; // this._touched || this.customValidation;
|
|
5086
|
+
const validityMessage = (showValidation ? this.validationMessage : '') ?? '';
|
|
5087
|
+
const invalid = validityMessage?.length > 0 || (!this.customValidation && this.inputElement?.checkValidity() === false);
|
|
5088
|
+
const validityMessageRender = html `<div
|
|
5089
|
+
role="alert"
|
|
5090
|
+
id="invalid-feedback-${this._id}"
|
|
5091
|
+
class="invalid-feedback form-feedback form-text form-feedback just-validate-error-label"
|
|
5092
|
+
?hidden=${!(validityMessage?.length > 0)}
|
|
5093
|
+
>
|
|
5094
|
+
<span class="visually-hidden">${this.label}: </span>${validityMessage}
|
|
5095
|
+
</div>`;
|
|
4504
5096
|
return html `
|
|
4505
5097
|
<div class="form-group" part="input-wrapper">
|
|
4506
5098
|
<label
|
|
4507
5099
|
for="${ifDefined(this._id || undefined)}"
|
|
4508
5100
|
part="label"
|
|
4509
5101
|
class="${this.composeClass('active', this.labelHidden ? 'visually-hidden' : '')}"
|
|
4510
|
-
|
|
4511
|
-
>
|
|
4512
|
-
|
|
4513
|
-
${when(this.slotted, () => html
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
5102
|
+
><slot name="label"></slot
|
|
5103
|
+
></label>
|
|
5104
|
+
|
|
5105
|
+
${when(this.slotted || this.type === 'number', () => html `<div
|
|
5106
|
+
class="${this.composeClass('input-group ', this.type === 'number' ? 'input-number' : '', this.type === 'number' && this.adaptive ? 'input-number-adaptive' : '', this.disabled ? 'disabled' : '', this.readonly ? 'readonly' : '')}"
|
|
5107
|
+
>
|
|
5108
|
+
${when(this._slotPrepend, () => html ` <span class="input-group-text">
|
|
5109
|
+
<slot name="prepend" @slotchange=${() => this.requestUpdate()}></slot
|
|
5110
|
+
></span>`)}
|
|
5111
|
+
${this._renderInput(supportTextId, invalid, validityMessage, showValidation)}
|
|
5112
|
+
${when(this.type === 'number', () => html `<span class="input-group-text align-buttons flex-column">
|
|
5113
|
+
<button
|
|
5114
|
+
class="input-number-add"
|
|
5115
|
+
@click=${() => this._inputNumberIncDec(1)}
|
|
5116
|
+
?disabled=${this.disabled || this.readonly}
|
|
5117
|
+
>
|
|
5118
|
+
<span class="visually-hidden">${this.$t('increaseValue')}</span>
|
|
5119
|
+
</button>
|
|
5120
|
+
<button
|
|
5121
|
+
class="input-number-sub"
|
|
5122
|
+
@click=${() => this._inputNumberIncDec(-1)}
|
|
5123
|
+
?disabled=${this.disabled || this.readonly}
|
|
5124
|
+
>
|
|
5125
|
+
<span class="visually-hidden">${this.$t('decreaseValue')}</span>
|
|
5126
|
+
</button>
|
|
5127
|
+
<div aria-live="polite" class="visually-hidden" id="${this._id}-live-region"></div>
|
|
5128
|
+
</span>`)}
|
|
5129
|
+
${when(this._slotAppend, () => html ` <div class="input-group-append">
|
|
5130
|
+
<slot name="append" @slotchange=${() => this.requestUpdate()}></slot>
|
|
5131
|
+
</div>`)}
|
|
4521
5132
|
</div>
|
|
4522
|
-
${supportTextRender} ${this._renderpasswordStrengthMeter()}`, () => html ` ${this._renderInput(supportTextId)} ${
|
|
5133
|
+
${validityMessageRender} ${supportTextRender} ${this._renderpasswordStrengthMeter()}`, () => html ` ${this._renderInput(supportTextId, invalid, validityMessage, showValidation)} ${validityMessageRender}
|
|
5134
|
+
${supportTextRender} ${this._renderpasswordStrengthMeter()}`)}
|
|
4523
5135
|
</div>
|
|
4524
5136
|
`;
|
|
4525
5137
|
}
|
|
4526
5138
|
};
|
|
4527
5139
|
ItInput.styles = styles;
|
|
4528
5140
|
__decorate([
|
|
4529
|
-
|
|
4530
|
-
__metadata("design:type", Object)
|
|
4531
|
-
], ItInput.prototype, "internals", void 0);
|
|
4532
|
-
__decorate([
|
|
4533
|
-
property({ type: Boolean }),
|
|
4534
|
-
__metadata("design:type", Object)
|
|
4535
|
-
], ItInput.prototype, "slotted", void 0);
|
|
4536
|
-
__decorate([
|
|
4537
|
-
property({ type: Boolean, reflect: true }) // from validity mixin
|
|
4538
|
-
,
|
|
4539
|
-
__metadata("design:type", Object)
|
|
4540
|
-
], ItInput.prototype, "invalid", void 0);
|
|
4541
|
-
__decorate([
|
|
4542
|
-
property({ type: Boolean, reflect: true, attribute: 'custom-validation' }) // from validity mixin
|
|
4543
|
-
,
|
|
5141
|
+
state(),
|
|
4544
5142
|
__metadata("design:type", Object)
|
|
4545
|
-
], ItInput.prototype, "
|
|
5143
|
+
], ItInput.prototype, "_slotPrepend", void 0);
|
|
4546
5144
|
__decorate([
|
|
4547
|
-
|
|
4548
|
-
,
|
|
5145
|
+
state(),
|
|
4549
5146
|
__metadata("design:type", Object)
|
|
4550
|
-
], ItInput.prototype, "
|
|
5147
|
+
], ItInput.prototype, "_slotAppend", void 0);
|
|
4551
5148
|
__decorate([
|
|
4552
|
-
property({
|
|
5149
|
+
property({ type: String }),
|
|
4553
5150
|
__metadata("design:type", String)
|
|
4554
|
-
], ItInput.prototype, "
|
|
4555
|
-
__decorate([
|
|
4556
|
-
query('input'),
|
|
4557
|
-
__metadata("design:type", HTMLInputElement)
|
|
4558
|
-
], ItInput.prototype, "_inputElement", void 0);
|
|
5151
|
+
], ItInput.prototype, "type", void 0);
|
|
4559
5152
|
__decorate([
|
|
4560
|
-
property(
|
|
5153
|
+
property(),
|
|
4561
5154
|
__metadata("design:type", Object)
|
|
4562
5155
|
], ItInput.prototype, "size", void 0);
|
|
4563
5156
|
__decorate([
|
|
4564
|
-
property({ type:
|
|
5157
|
+
property({ type: Boolean }),
|
|
4565
5158
|
__metadata("design:type", Object)
|
|
4566
|
-
], ItInput.prototype, "
|
|
5159
|
+
], ItInput.prototype, "adaptive", void 0);
|
|
4567
5160
|
__decorate([
|
|
4568
5161
|
property({ type: Boolean, attribute: 'label-hidden' }),
|
|
4569
5162
|
__metadata("design:type", Object)
|
|
4570
5163
|
], ItInput.prototype, "labelHidden", void 0);
|
|
4571
|
-
__decorate([
|
|
4572
|
-
property({ type: String }),
|
|
4573
|
-
__metadata("design:type", String)
|
|
4574
|
-
], ItInput.prototype, "type", void 0);
|
|
4575
|
-
__decorate([
|
|
4576
|
-
property({ type: String }),
|
|
4577
|
-
__metadata("design:type", Object)
|
|
4578
|
-
], ItInput.prototype, "name", void 0);
|
|
4579
5164
|
__decorate([
|
|
4580
5165
|
property({ type: String }),
|
|
4581
5166
|
__metadata("design:type", Object)
|
|
@@ -4584,10 +5169,6 @@ __decorate([
|
|
|
4584
5169
|
property({ type: String, attribute: 'support-text' }),
|
|
4585
5170
|
__metadata("design:type", Object)
|
|
4586
5171
|
], ItInput.prototype, "supportText", void 0);
|
|
4587
|
-
__decorate([
|
|
4588
|
-
property({ type: Boolean }),
|
|
4589
|
-
__metadata("design:type", Object)
|
|
4590
|
-
], ItInput.prototype, "disabled", void 0);
|
|
4591
5172
|
__decorate([
|
|
4592
5173
|
property({ type: Boolean }),
|
|
4593
5174
|
__metadata("design:type", Object)
|
|
@@ -4605,17 +5186,9 @@ __decorate([
|
|
|
4605
5186
|
__metadata("design:type", Object)
|
|
4606
5187
|
], ItInput.prototype, "suggestions", void 0);
|
|
4607
5188
|
__decorate([
|
|
4608
|
-
|
|
4609
|
-
__metadata("design:type",
|
|
4610
|
-
], ItInput.prototype, "
|
|
4611
|
-
__decorate([
|
|
4612
|
-
property({ type: Number }),
|
|
4613
|
-
__metadata("design:type", Object)
|
|
4614
|
-
], ItInput.prototype, "maxlength", void 0);
|
|
4615
|
-
__decorate([
|
|
4616
|
-
property({ type: String }),
|
|
4617
|
-
__metadata("design:type", String)
|
|
4618
|
-
], ItInput.prototype, "pattern", void 0);
|
|
5189
|
+
queryAssignedElements({ slot: 'label' }),
|
|
5190
|
+
__metadata("design:type", Array)
|
|
5191
|
+
], ItInput.prototype, "labelElements", void 0);
|
|
4619
5192
|
__decorate([
|
|
4620
5193
|
state(),
|
|
4621
5194
|
__metadata("design:type", Object)
|
|
@@ -4628,24 +5201,7 @@ __decorate([
|
|
|
4628
5201
|
state(),
|
|
4629
5202
|
__metadata("design:type", Object)
|
|
4630
5203
|
], ItInput.prototype, "_score", void 0);
|
|
4631
|
-
__decorate([
|
|
4632
|
-
state(),
|
|
4633
|
-
__metadata("design:type", Object)
|
|
4634
|
-
], ItInput.prototype, "_value", void 0);
|
|
4635
|
-
__decorate([
|
|
4636
|
-
state(),
|
|
4637
|
-
__metadata("design:type", Object)
|
|
4638
|
-
], ItInput.prototype, "_touched", void 0);
|
|
4639
|
-
__decorate([
|
|
4640
|
-
property({ type: String }),
|
|
4641
|
-
__metadata("design:type", String)
|
|
4642
|
-
], ItInput.prototype, "validityMessage", void 0);
|
|
4643
|
-
__decorate([
|
|
4644
|
-
property({ reflect: true }),
|
|
4645
|
-
__metadata("design:type", Object),
|
|
4646
|
-
__metadata("design:paramtypes", [Object])
|
|
4647
|
-
], ItInput.prototype, "value", null);
|
|
4648
|
-
ItInput = __decorate([
|
|
5204
|
+
ItInput = ItInput_1 = __decorate([
|
|
4649
5205
|
customElement('it-input')
|
|
4650
5206
|
], ItInput);
|
|
4651
5207
|
|