@italia/input 0.1.0-alpha.2 → 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.
@@ -439,6 +439,7 @@ const interactions = new WeakMap();
439
439
  /** A reactive controller to allow form controls to participate in form submission, validation, etc. */
440
440
  class FormControlController {
441
441
  constructor(host, options) {
442
+ this.submittedOnce = false;
442
443
  this.handleFormData = (event) => {
443
444
  // console.log('handleFormData');
444
445
  const disabled = this.options.disabled(this.host);
@@ -460,6 +461,17 @@ class FormControlController {
460
461
  event.formData.append(name, value);
461
462
  }
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;
463
475
  default:
464
476
  if (Array.isArray(value)) {
465
477
  value.forEach((val) => {
@@ -481,13 +493,30 @@ class FormControlController {
481
493
  this.setUserInteracted(control, true);
482
494
  });
483
495
  }
484
- if (this.form && !this.form.noValidate && !disabled && !reportValidity(this.host)) {
496
+ const resReportValidity = reportValidity(this.host);
497
+ if (this.form && !this.form.noValidate && !disabled && !resReportValidity) {
485
498
  event.preventDefault();
486
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
+ }
487
514
  }
515
+ this.submittedOnce = true;
488
516
  };
489
517
  this.handleFormReset = () => {
490
518
  this.options.setValue(this.host, '');
519
+ this.submittedOnce = false;
491
520
  this.setUserInteracted(this.host, false);
492
521
  interactions.set(this.host, []);
493
522
  };
@@ -652,6 +681,7 @@ class FormControlController {
652
681
  if (!formCollection) {
653
682
  return;
654
683
  }
684
+ this.submittedOnce = false;
655
685
  // Remove this host from the form's collection
656
686
  formCollection.delete(this.host);
657
687
  // Check to make sure there's no other form controls in the collection. If we do this
@@ -748,6 +778,10 @@ class FormControlController {
748
778
  host.toggleAttribute('data-user-invalid', !isValid && hasInteracted);
749
779
  host.toggleAttribute('data-user-valid', isValid && hasInteracted);
750
780
  }
781
+ userInteracted() {
782
+ const hasInteracted = Boolean(userInteractedControls.has(this.host));
783
+ return hasInteracted;
784
+ }
751
785
  /**
752
786
  * Updates the form control's validity based on the current value of `host.validity.valid`. Call this when anything
753
787
  * that affects constraint validation changes so the component receives the correct validity states.
@@ -784,6 +818,7 @@ const translation$1 = {
784
818
  $name: 'Italiano',
785
819
  $dir: 'ltr',
786
820
  validityRequired: 'Questo campo è obbligatorio.',
821
+ validityGroupRequired: "Scegli almeno un'opzione",
787
822
  validityPattern: 'Il valore non corrisponde al formato richiesto.',
788
823
  validityMinlength: 'Il valore deve essere lungo almeno {minlength} caratteri.',
789
824
  validityMaxlength: 'Il valore deve essere lungo al massimo {maxlength} caratteri.',
@@ -828,24 +863,27 @@ class FormControl extends BaseLocalizedComponent {
828
863
  this.maxlength = -1;
829
864
  /** If the input is required. */
830
865
  this.required = false;
866
+ /* For grouped input, like checkbox-group */
867
+ this.isInGroup = false;
831
868
  this.validationMessage = '';
832
869
  }
833
870
  /** Gets the validity state object */
834
871
  get validity() {
835
872
  return this.inputElement?.validity;
836
873
  }
874
+ /** Gets the associated form, if one exists. */
875
+ getForm() {
876
+ return this.formControlController.getForm();
877
+ }
837
878
  // Form validation methods
838
879
  checkValidity() {
839
880
  const inputValid = this.inputElement?.checkValidity() ?? true; // this.inputElement.checkValidity() è la validazione del browser
840
881
  return inputValid;
841
882
  }
842
- /** Gets the associated form, if one exists. */
843
- getForm() {
844
- return this.formControlController.getForm();
845
- }
846
883
  /** Checks for validity and shows the browser's validation message if the control is invalid. */
847
884
  reportValidity() {
848
- const ret = this.inputElement.checkValidity();
885
+ // const ret = this.inputElement.checkValidity();
886
+ const ret = this.checkValidity(); // chiama la checkValidity, che se è stata overridata chiama quella
849
887
  this.handleValidationMessages();
850
888
  return ret; // this.inputElement.reportValidity();
851
889
  }
@@ -890,7 +928,8 @@ class FormControl extends BaseLocalizedComponent {
890
928
  handleValidationMessages() {
891
929
  if (!this.customValidation) {
892
930
  const _v = this.inputElement.validity;
893
- if (_v.valueMissing) {
931
+ const isRequiredHandledByGroup = this.isInGroup === true;
932
+ if (_v.valueMissing && !isRequiredHandledByGroup) {
894
933
  this.setCustomValidity(this.$t('validityRequired'));
895
934
  }
896
935
  else if (_v.patternMismatch) {
@@ -961,7 +1000,7 @@ class FormControl extends BaseLocalizedComponent {
961
1000
  if (this.customValidation) {
962
1001
  this.setCustomValidity(this.validationText ?? '');
963
1002
  }
964
- else {
1003
+ else if (this.formControlController.userInteracted()) {
965
1004
  this.formControlController.updateValidity();
966
1005
  }
967
1006
  }
@@ -1029,11 +1068,23 @@ __decorate([
1029
1068
  ,
1030
1069
  __metadata("design:type", Object)
1031
1070
  ], FormControl.prototype, "required", void 0);
1071
+ __decorate([
1072
+ property({ type: Boolean }),
1073
+ __metadata("design:type", Object)
1074
+ ], FormControl.prototype, "isInGroup", void 0);
1032
1075
  __decorate([
1033
1076
  state(),
1034
1077
  __metadata("design:type", Object)
1035
1078
  ], FormControl.prototype, "validationMessage", void 0);
1036
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
+ };
1086
+ }
1087
+
1037
1088
  /**
1038
1089
  * Checks for repetition of characters in
1039
1090
  * a string
@@ -1341,11 +1392,6 @@ a:hover {
1341
1392
  color: var(--bs-color-link-hover);
1342
1393
  }
1343
1394
 
1344
- a:not([href]):not([class]), a:not([href]):not([class]):hover {
1345
- color: inherit;
1346
- text-decoration: none;
1347
- }
1348
-
1349
1395
  pre,
1350
1396
  code,
1351
1397
  kbd,
@@ -1587,6 +1633,9 @@ progress {
1587
1633
  transition: all var(--bs-transition-instant) ease-in-out;
1588
1634
  user-select: none;
1589
1635
  }
1636
+ .btn:hover {
1637
+ color: var(--bs-btn-text-color);
1638
+ }
1590
1639
  .btn:disabled, .btn.disabled {
1591
1640
  opacity: var(--bs-btn-disabled-opacity);
1592
1641
  cursor: not-allowed;
@@ -4717,6 +4766,10 @@ select.just-validate-success-field {
4717
4766
  .password-icon {
4718
4767
  top: calc(var(--bs-form-control-spacing) * 5);
4719
4768
  --bs-icon-default: var(--bs-icon-primary);
4769
+ }
4770
+
4771
+ .is-invalid + .input-group-text.align-buttons {
4772
+ bottom: 0 !important;
4720
4773
  }`;
4721
4774
 
4722
4775
  var ItInput_1;
@@ -4788,7 +4841,7 @@ let ItInput = ItInput_1 = class ItInput extends FormControl {
4788
4841
  this.logger.warn("The suggestions property is enabled, but type isn't password. Please, remove suggestions this property.");
4789
4842
  }
4790
4843
  if (!this.label || this.label?.length === 0) {
4791
- 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.`);
4792
4845
  }
4793
4846
  }
4794
4847
  _handleInput(e) {
@@ -4953,9 +5006,9 @@ let ItInput = ItInput_1 = class ItInput extends FormControl {
4953
5006
  }
4954
5007
  return nothing;
4955
5008
  }
4956
- _renderInput(supportTextId, invalid, validityMessage) {
4957
- const ariaDescribedBy = this.composeClass(this.supportText?.length > 0 ? supportTextId : '', this.passwordStrengthMeter ? `strengthMeterInfo_${this._id}` : '', this._ariaAttributes['aria-describedby']?.length > 0 ? this._ariaAttributes['aria-describedby'] : '', validityMessage?.length > 0 ? `invalid-feedback-${this._id}` : '');
4958
- const inputClasses = this.composeClass('it-form__control', this.plaintext ? 'form-control-plaintext' : 'form-control', this.size ? `form-control-${this.size}` : '', invalid ? 'is-invalid' : '', !invalid && this._touched && !this.readonly ? 'just-validate-success-field' : '');
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' : '');
4959
5012
  let inputRender;
4960
5013
  if (this.type === 'textarea') {
4961
5014
  inputRender = html `
@@ -4963,7 +5016,7 @@ let ItInput = ItInput_1 = class ItInput extends FormControl {
4963
5016
  part="textarea focusable"
4964
5017
  ${setAttributes(this._ariaAttributes)}
4965
5018
  aria-describedby=${ifDefined(ariaDescribedBy || undefined)}
4966
- ?aria-invalid=${invalid}
5019
+ aria-invalid=${ifDefined(invalid ? 'true' : undefined)}
4967
5020
  @input="${this._handleInput}"
4968
5021
  @blur=${this._handleBlur}
4969
5022
  @focus=${this._handleFocus}
@@ -4995,7 +5048,7 @@ let ItInput = ItInput_1 = class ItInput extends FormControl {
4995
5048
  part="input focusable"
4996
5049
  ${setAttributes(this._ariaAttributes)}
4997
5050
  aria-describedby=${ifDefined(ariaDescribedBy || undefined)}
4998
- ?aria-invalid=${invalid}
5051
+ aria-invalid=${ifDefined(invalid ? 'true' : undefined)}
4999
5052
  @input="${this._handleInput}"
5000
5053
  @blur=${this._handleBlur}
5001
5054
  @focus=${this._handleFocus}
@@ -5013,6 +5066,7 @@ let ItInput = ItInput_1 = class ItInput extends FormControl {
5013
5066
  min=${ifDefined(this.min)}
5014
5067
  max=${ifDefined(this.max)}
5015
5068
  step=${ifDefined(this.step)}
5069
+ autocomplete="off"
5016
5070
  pattern=${ifDefined(this.pattern)}
5017
5071
  ?formNoValidate=${this.customValidation}
5018
5072
  .value="${live(this.value)}"
@@ -5028,7 +5082,8 @@ let ItInput = ItInput_1 = class ItInput extends FormControl {
5028
5082
  render() {
5029
5083
  const supportTextId = `${this._id}-support-text`;
5030
5084
  const supportTextRender = html ` ${when(this.supportText, () => html ` <small class="form-text" id="${supportTextId}">${this.supportText}</small> `)}`;
5031
- const validityMessage = (this.validationMessage ) ?? '';
5085
+ const showValidation = this.formControlController.submittedOnce || this.customValidation; // true; // this._touched || this.customValidation;
5086
+ const validityMessage = (showValidation ? this.validationMessage : '') ?? '';
5032
5087
  const invalid = validityMessage?.length > 0 || (!this.customValidation && this.inputElement?.checkValidity() === false);
5033
5088
  const validityMessageRender = html `<div
5034
5089
  role="alert"
@@ -5053,7 +5108,7 @@ let ItInput = ItInput_1 = class ItInput extends FormControl {
5053
5108
  ${when(this._slotPrepend, () => html ` <span class="input-group-text">
5054
5109
  <slot name="prepend" @slotchange=${() => this.requestUpdate()}></slot
5055
5110
  ></span>`)}
5056
- ${this._renderInput(supportTextId, invalid, validityMessage)}
5111
+ ${this._renderInput(supportTextId, invalid, validityMessage, showValidation)}
5057
5112
  ${when(this.type === 'number', () => html `<span class="input-group-text align-buttons flex-column">
5058
5113
  <button
5059
5114
  class="input-number-add"
@@ -5075,7 +5130,7 @@ let ItInput = ItInput_1 = class ItInput extends FormControl {
5075
5130
  <slot name="append" @slotchange=${() => this.requestUpdate()}></slot>
5076
5131
  </div>`)}
5077
5132
  </div>
5078
- ${validityMessageRender} ${supportTextRender} ${this._renderpasswordStrengthMeter()}`, () => html ` ${this._renderInput(supportTextId, invalid, validityMessage)} ${validityMessageRender}
5133
+ ${validityMessageRender} ${supportTextRender} ${this._renderpasswordStrengthMeter()}`, () => html ` ${this._renderInput(supportTextId, invalid, validityMessage, showValidation)} ${validityMessageRender}
5079
5134
  ${supportTextRender} ${this._renderpasswordStrengthMeter()}`)}
5080
5135
  </div>
5081
5136
  `;