@govtechsg/sgds-web-component 3.0.6 → 3.1.0-rc.1

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.
Files changed (29) hide show
  1. package/components/Checkbox/checkbox-group.js +1 -1
  2. package/components/Checkbox/checkbox.js +1 -1
  3. package/components/Checkbox/index.umd.js +196 -31
  4. package/components/Checkbox/index.umd.js.map +1 -1
  5. package/components/Checkbox/sgds-checkbox-group.d.ts +49 -10
  6. package/components/Checkbox/sgds-checkbox-group.js +162 -25
  7. package/components/Checkbox/sgds-checkbox-group.js.map +1 -1
  8. package/components/Checkbox/sgds-checkbox.d.ts +5 -1
  9. package/components/Checkbox/sgds-checkbox.js +39 -6
  10. package/components/Checkbox/sgds-checkbox.js.map +1 -1
  11. package/components/ComboBox/index.umd.js +39 -6
  12. package/components/ComboBox/index.umd.js.map +1 -1
  13. package/components/index.umd.js +196 -31
  14. package/components/index.umd.js.map +1 -1
  15. package/index.umd.js +196 -31
  16. package/index.umd.js.map +1 -1
  17. package/package.json +1 -1
  18. package/react/components/Checkbox/checkbox-group.cjs.js +1 -1
  19. package/react/components/Checkbox/checkbox-group.js +1 -1
  20. package/react/components/Checkbox/checkbox.cjs.js +1 -1
  21. package/react/components/Checkbox/checkbox.js +1 -1
  22. package/react/components/Checkbox/sgds-checkbox-group.cjs.js +161 -24
  23. package/react/components/Checkbox/sgds-checkbox-group.cjs.js.map +1 -1
  24. package/react/components/Checkbox/sgds-checkbox-group.js +162 -25
  25. package/react/components/Checkbox/sgds-checkbox-group.js.map +1 -1
  26. package/react/components/Checkbox/sgds-checkbox.cjs.js +38 -5
  27. package/react/components/Checkbox/sgds-checkbox.cjs.js.map +1 -1
  28. package/react/components/Checkbox/sgds-checkbox.js +39 -6
  29. package/react/components/Checkbox/sgds-checkbox.js.map +1 -1
@@ -1,6 +1,6 @@
1
1
  import { css } from 'lit';
2
2
 
3
- var css_248z = css`:host{--sgds-checkbox-group-gap:var(--sgds-spacer-2)}fieldset{border:0;gap:var(--sgds-form-gap-md);margin:0;min-width:0;padding:0}.label-hint-container,fieldset{display:flex;flex-direction:column}.label-hint-container{gap:var(--sgds-form-gap-sm)}.label-hint-container .form-label{color:var(--sgds-form-color-default);font-size:var(--sgds-font-size-2);font-weight:var(--sgds-font-weight-regular)}.checkbox-container{display:flex;flex-direction:column;gap:var(--sgds-form-gap-md)}`;
3
+ var css_248z = css`:host{--sgds-checkbox-group-gap:var(--sgds-spacer-2)}fieldset{border:0;gap:var(--sgds-form-gap-md);margin:0;min-width:0;padding:0}.label-hint-container,fieldset{display:flex;flex-direction:column}.label-hint-container{gap:var(--sgds-form-gap-sm)}.label-hint-container .form-label{color:var(--sgds-form-color-default);font-size:var(--sgds-font-size-2);font-weight:var(--sgds-font-weight-regular)}.checkbox-container{display:flex;flex-direction:column;gap:var(--sgds-form-gap-md)}.checkbox-group-validation-input{display:none}`;
4
4
 
5
5
  export { css_248z as default };
6
6
  //# sourceMappingURL=checkbox-group.js.map
@@ -1,6 +1,6 @@
1
1
  import { css } from 'lit';
2
2
 
3
- var css_248z = css`input{margin:0}.form-check{display:flex;gap:var(--sgds-form-gap-md);padding:var(--sgds-form-padding-inline-sm) 0}.form-check-input,.form-check-input-container{height:var(--sgds-form-height-sm);width:var(--sgds-form-width-xs)}.form-check-input{appearance:none;background-color:var(--sgds-form-surface-default);background-image:var(--sgds-radio-bg-image);background-position:50%;background-repeat:no-repeat;background-size:auto;border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-default);border-radius:var(--sgds-form-border-radius-md)}:host(:not([disabled]):not([invalid]):not([checked]):not([indeterminate])) .form-check-input:hover{border:var(--sgds-form-border-width-thick) solid var(--sgds-border-color-emphasis)}.form-check-input:focus,.form-check-input:focus-visible{border:var(--sgds-form-border-width-thick) solid var(--sgds-border-color-emphasis);box-shadow:var(--sgds-form-box-shadow-focus);outline:0}.form-check-input:checked,.form-check-input[checked]{--sgds-radio-bg-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" fill="none"><path d="M14.347 3.979a.522.522 0 0 1 0 .739L7.043 12.02a.521.521 0 0 1-.738 0L2.653 8.369a.522.522 0 1 1 .739-.738l3.282 3.283 6.934-6.935a.52.52 0 0 1 .739 0Z" fill="%23fff"/></svg>');background-color:var(--sgds-form-primary-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-input:checked:focus,.form-check-input:checked:hover,.form-check-input[checked]:focus-visible,.form-check-input[checked]:hover{background-color:var(--sgds-form-primary-surface-emphasis)}.form-check-input:indeterminate,.form-check-input[indeterminate]{--sgds-radio-bg-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5Z" fill="%23fff"/></svg>');background-color:var(--sgds-form-primary-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-input:indeterminate:focus,.form-check-input:indeterminate:hover,.form-check-input[indeterminate]:focus-visible,.form-check-input[indeterminate]:hover{background-color:var(--sgds-form-primary-surface-emphasis)}:host([disabled]) .form-check{cursor:not-allowed;opacity:var(--sgds-opacity-50)}.form-check-input.is-invalid{border:var(--sgds-form-border-width-thick) solid var(--sgds-form-danger-border-color-default)}.form-check-input:checked.is-invalid,.form-check-input:indeterminate.is-invalid,.form-check-input[checked].is-invalid,.form-check-input[indeterminate].is-invalid{background-color:var(--sgds-form-danger-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-label{width:100%}`;
3
+ var css_248z = css`input{margin:0}.form-check{display:flex;gap:var(--sgds-form-gap-md);margin-bottom:var(--sgds-margin-3-xs);padding:var(--sgds-form-padding-inline-sm) 0}.form-check-input,.form-check-input-container{height:var(--sgds-form-height-sm);width:var(--sgds-form-width-xs)}.form-check-input{appearance:none;background-color:var(--sgds-form-surface-default);background-image:var(--sgds-radio-bg-image);background-position:50%;background-repeat:no-repeat;background-size:auto;border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-default);border-radius:var(--sgds-form-border-radius-md)}:host(:not([disabled]):not([invalid]):not([checked]):not([indeterminate])) .form-check-input:hover{border:var(--sgds-form-border-width-thick) solid var(--sgds-border-color-emphasis)}.form-check-input:focus,.form-check-input:focus-visible{border:var(--sgds-form-border-width-thick) solid var(--sgds-border-color-emphasis);box-shadow:var(--sgds-form-box-shadow-focus);outline:0}.form-check-input:checked,.form-check-input[checked]{--sgds-radio-bg-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" fill="none"><path d="M14.347 3.979a.522.522 0 0 1 0 .739L7.043 12.02a.521.521 0 0 1-.738 0L2.653 8.369a.522.522 0 1 1 .739-.738l3.282 3.283 6.934-6.935a.52.52 0 0 1 .739 0Z" fill="%23fff"/></svg>');background-color:var(--sgds-form-primary-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-input:checked:focus,.form-check-input:checked:hover,.form-check-input[checked]:focus-visible,.form-check-input[checked]:hover{background-color:var(--sgds-form-primary-surface-emphasis)}.form-check-input:indeterminate,.form-check-input[indeterminate]{--sgds-radio-bg-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5Z" fill="%23fff"/></svg>');background-color:var(--sgds-form-primary-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-input:indeterminate:focus,.form-check-input:indeterminate:hover,.form-check-input[indeterminate]:focus-visible,.form-check-input[indeterminate]:hover{background-color:var(--sgds-form-primary-surface-emphasis)}:host([disabled]) .form-check{cursor:not-allowed;opacity:var(--sgds-opacity-50)}.form-check-input.is-invalid{border:var(--sgds-form-border-width-thick) solid var(--sgds-form-danger-border-color-default)}.form-check-input:checked.is-invalid,.form-check-input:indeterminate.is-invalid,.form-check-input[checked].is-invalid,.form-check-input[indeterminate].is-invalid{background-color:var(--sgds-form-danger-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-label{width:100%}`;
4
4
 
5
5
  export { css_248z as default };
6
6
  //# sourceMappingURL=checkbox.js.map
@@ -4893,7 +4893,7 @@
4893
4893
  };
4894
4894
  }
4895
4895
 
4896
- var css_248z$1 = css`input{margin:0}.form-check{display:flex;gap:var(--sgds-form-gap-md);padding:var(--sgds-form-padding-inline-sm) 0}.form-check-input,.form-check-input-container{height:var(--sgds-form-height-sm);width:var(--sgds-form-width-xs)}.form-check-input{appearance:none;background-color:var(--sgds-form-surface-default);background-image:var(--sgds-radio-bg-image);background-position:50%;background-repeat:no-repeat;background-size:auto;border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-default);border-radius:var(--sgds-form-border-radius-md)}:host(:not([disabled]):not([invalid]):not([checked]):not([indeterminate])) .form-check-input:hover{border:var(--sgds-form-border-width-thick) solid var(--sgds-border-color-emphasis)}.form-check-input:focus,.form-check-input:focus-visible{border:var(--sgds-form-border-width-thick) solid var(--sgds-border-color-emphasis);box-shadow:var(--sgds-form-box-shadow-focus);outline:0}.form-check-input:checked,.form-check-input[checked]{--sgds-radio-bg-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" fill="none"><path d="M14.347 3.979a.522.522 0 0 1 0 .739L7.043 12.02a.521.521 0 0 1-.738 0L2.653 8.369a.522.522 0 1 1 .739-.738l3.282 3.283 6.934-6.935a.52.52 0 0 1 .739 0Z" fill="%23fff"/></svg>');background-color:var(--sgds-form-primary-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-input:checked:focus,.form-check-input:checked:hover,.form-check-input[checked]:focus-visible,.form-check-input[checked]:hover{background-color:var(--sgds-form-primary-surface-emphasis)}.form-check-input:indeterminate,.form-check-input[indeterminate]{--sgds-radio-bg-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5Z" fill="%23fff"/></svg>');background-color:var(--sgds-form-primary-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-input:indeterminate:focus,.form-check-input:indeterminate:hover,.form-check-input[indeterminate]:focus-visible,.form-check-input[indeterminate]:hover{background-color:var(--sgds-form-primary-surface-emphasis)}:host([disabled]) .form-check{cursor:not-allowed;opacity:var(--sgds-opacity-50)}.form-check-input.is-invalid{border:var(--sgds-form-border-width-thick) solid var(--sgds-form-danger-border-color-default)}.form-check-input:checked.is-invalid,.form-check-input:indeterminate.is-invalid,.form-check-input[checked].is-invalid,.form-check-input[indeterminate].is-invalid{background-color:var(--sgds-form-danger-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-label{width:100%}`;
4896
+ var css_248z$1 = css`input{margin:0}.form-check{display:flex;gap:var(--sgds-form-gap-md);margin-bottom:var(--sgds-margin-3-xs);padding:var(--sgds-form-padding-inline-sm) 0}.form-check-input,.form-check-input-container{height:var(--sgds-form-height-sm);width:var(--sgds-form-width-xs)}.form-check-input{appearance:none;background-color:var(--sgds-form-surface-default);background-image:var(--sgds-radio-bg-image);background-position:50%;background-repeat:no-repeat;background-size:auto;border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-default);border-radius:var(--sgds-form-border-radius-md)}:host(:not([disabled]):not([invalid]):not([checked]):not([indeterminate])) .form-check-input:hover{border:var(--sgds-form-border-width-thick) solid var(--sgds-border-color-emphasis)}.form-check-input:focus,.form-check-input:focus-visible{border:var(--sgds-form-border-width-thick) solid var(--sgds-border-color-emphasis);box-shadow:var(--sgds-form-box-shadow-focus);outline:0}.form-check-input:checked,.form-check-input[checked]{--sgds-radio-bg-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" fill="none"><path d="M14.347 3.979a.522.522 0 0 1 0 .739L7.043 12.02a.521.521 0 0 1-.738 0L2.653 8.369a.522.522 0 1 1 .739-.738l3.282 3.283 6.934-6.935a.52.52 0 0 1 .739 0Z" fill="%23fff"/></svg>');background-color:var(--sgds-form-primary-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-input:checked:focus,.form-check-input:checked:hover,.form-check-input[checked]:focus-visible,.form-check-input[checked]:hover{background-color:var(--sgds-form-primary-surface-emphasis)}.form-check-input:indeterminate,.form-check-input[indeterminate]{--sgds-radio-bg-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="17" height="16" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 8a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5Z" fill="%23fff"/></svg>');background-color:var(--sgds-form-primary-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-input:indeterminate:focus,.form-check-input:indeterminate:hover,.form-check-input[indeterminate]:focus-visible,.form-check-input[indeterminate]:hover{background-color:var(--sgds-form-primary-surface-emphasis)}:host([disabled]) .form-check{cursor:not-allowed;opacity:var(--sgds-opacity-50)}.form-check-input.is-invalid{border:var(--sgds-form-border-width-thick) solid var(--sgds-form-danger-border-color-default)}.form-check-input:checked.is-invalid,.form-check-input:indeterminate.is-invalid,.form-check-input[checked].is-invalid,.form-check-input[indeterminate].is-invalid{background-color:var(--sgds-form-danger-surface-default);border:var(--sgds-form-border-width-default) solid var(--sgds-border-color-transparent)}.form-check-label{width:100%}`;
4897
4897
 
4898
4898
  /**
4899
4899
  * @summary Checkbox component is used when you require users to select multiple items from a list.
@@ -4910,14 +4910,14 @@
4910
4910
  super(...arguments);
4911
4911
  /** Draws the checkbox in a checked state. */
4912
4912
  this.checked = false;
4913
- /** Allows invalidFeedback, invalid and valid styles to be visible with the input */
4914
- this.hasFeedback = false;
4915
4913
  /** Gets or sets the default value used to reset this element. The initial value corresponds to the one originally specified in the HTML that created this element. */
4916
4914
  this.defaultChecked = false;
4917
4915
  /** Marks the checkbox input as indeterminate , with indeterminate logo */
4918
4916
  this.indeterminate = false;
4919
4917
  /** Makes the checkbox a required field. */
4920
4918
  this.required = false;
4919
+ /**Feedback text for error state when validated */
4920
+ this.invalidFeedback = "";
4921
4921
  this._isTouched = false;
4922
4922
  }
4923
4923
  _handleInvalidChange() {
@@ -4942,7 +4942,6 @@
4942
4942
  this.indeterminate = !this.indeterminate;
4943
4943
  }
4944
4944
  this.checked = !this.checked;
4945
- this.value = this.input.value;
4946
4945
  super._mixinHandleChange(e);
4947
4946
  this.emit("sgds-change", { detail: { checked: this.checked, value: this.value } });
4948
4947
  }
@@ -4973,6 +4972,11 @@
4973
4972
  this.invalid = !this.input.checkValidity();
4974
4973
  }
4975
4974
  }
4975
+ _handleChecked() {
4976
+ this.checked
4977
+ ? this.emit("sgds-check", { detail: { value: this.value } })
4978
+ : this.emit("sgds-uncheck", { detail: { value: this.value } });
4979
+ }
4976
4980
  _mixinResetFormControl() {
4977
4981
  this._isTouched = false;
4978
4982
  this.checked = this.input.checked = this.defaultChecked;
@@ -5004,14 +5008,20 @@
5004
5008
  get validationMessage() {
5005
5009
  return this._mixinGetValidationMessage();
5006
5010
  }
5011
+ firstUpdated(_changedProperties) {
5012
+ super.firstUpdated(_changedProperties);
5013
+ this.checked && this.emit("sgds-check", { detail: { value: this.value } });
5014
+ }
5007
5015
  render() {
5016
+ const wantFeedbackStyle = this.hasFeedback === "both" || this.hasFeedback === "style";
5017
+ const wantFeedbackText = this.hasFeedback === "both" || this.hasFeedback === "text";
5008
5018
  return html `
5009
5019
  <div class="form-check">
5010
5020
  <div class="form-check-input-container">
5011
5021
  <input
5012
5022
  class=${classMap({
5013
5023
  "form-check-input": true,
5014
- "is-invalid": this.hasFeedback && this.invalid
5024
+ "is-invalid": wantFeedbackStyle && this.invalid
5015
5025
  })}
5016
5026
  type="checkbox"
5017
5027
  id=${this._controlId}
@@ -5033,6 +5043,23 @@
5033
5043
  </div>
5034
5044
  <label for="${this._controlId}" class="form-check-label" id="${this._labelId}"><slot></slot></label>
5035
5045
  </div>
5046
+ ${wantFeedbackText && this.invalid
5047
+ ? html `
5048
+ <div class="invalid-feedback-container">
5049
+ <slot name="invalidIcon">
5050
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
5051
+ <path
5052
+ d="M17.5 10C17.5 14.1421 14.1421 17.5 10 17.5C5.85786 17.5 2.5 14.1421 2.5 10C2.5 5.85786 5.85786 2.5 10 2.5C14.1421 2.5 17.5 5.85786 17.5 10ZM10 6.25C9.49805 6.25 9.10584 6.68339 9.15578 7.18285L9.48461 10.4711C9.51109 10.7359 9.7339 10.9375 10 10.9375C10.2661 10.9375 10.4889 10.7359 10.5154 10.4711L10.8442 7.18285C10.8942 6.68339 10.5019 6.25 10 6.25ZM10.0014 11.875C9.48368 11.875 9.06394 12.2947 9.06394 12.8125C9.06394 13.3303 9.48368 13.75 10.0014 13.75C10.5192 13.75 10.9389 13.3303 10.9389 12.8125C10.9389 12.2947 10.5192 11.875 10.0014 11.875Z"
5053
+ fill="currentColor"
5054
+ />
5055
+ </svg>
5056
+ </slot>
5057
+ <div id="checkbox-feedback" tabindex="0" class="invalid-feedback">
5058
+ ${this.invalidFeedback ? this.invalidFeedback : this.input.validationMessage}
5059
+ </div>
5060
+ </div>
5061
+ `
5062
+ : nothing}
5036
5063
  `;
5037
5064
  }
5038
5065
  }
@@ -5044,7 +5071,7 @@
5044
5071
  property({ type: Boolean, reflect: true })
5045
5072
  ], SgdsCheckbox.prototype, "checked", void 0);
5046
5073
  __decorate([
5047
- property({ type: Boolean, reflect: true })
5074
+ property({ type: String, reflect: true })
5048
5075
  ], SgdsCheckbox.prototype, "hasFeedback", void 0);
5049
5076
  __decorate([
5050
5077
  defaultValue("checked")
@@ -5055,6 +5082,9 @@
5055
5082
  __decorate([
5056
5083
  property({ type: Boolean, reflect: true })
5057
5084
  ], SgdsCheckbox.prototype, "required", void 0);
5085
+ __decorate([
5086
+ property({ type: String, reflect: true })
5087
+ ], SgdsCheckbox.prototype, "invalidFeedback", void 0);
5058
5088
  __decorate([
5059
5089
  state()
5060
5090
  ], SgdsCheckbox.prototype, "_isTouched", void 0);
@@ -5067,8 +5097,11 @@
5067
5097
  __decorate([
5068
5098
  watch("_isTouched", { waitUntilFirstUpdate: true })
5069
5099
  ], SgdsCheckbox.prototype, "_handleIsTouched", null);
5100
+ __decorate([
5101
+ watch("checked", { waitUntilFirstUpdate: true })
5102
+ ], SgdsCheckbox.prototype, "_handleChecked", null);
5070
5103
 
5071
- var css_248z = css`:host{--sgds-checkbox-group-gap:var(--sgds-spacer-2)}fieldset{border:0;gap:var(--sgds-form-gap-md);margin:0;min-width:0;padding:0}.label-hint-container,fieldset{display:flex;flex-direction:column}.label-hint-container{gap:var(--sgds-form-gap-sm)}.label-hint-container .form-label{color:var(--sgds-form-color-default);font-size:var(--sgds-font-size-2);font-weight:var(--sgds-font-weight-regular)}.checkbox-container{display:flex;flex-direction:column;gap:var(--sgds-form-gap-md)}`;
5104
+ var css_248z = css`:host{--sgds-checkbox-group-gap:var(--sgds-spacer-2)}fieldset{border:0;gap:var(--sgds-form-gap-md);margin:0;min-width:0;padding:0}.label-hint-container,fieldset{display:flex;flex-direction:column}.label-hint-container{gap:var(--sgds-form-gap-sm)}.label-hint-container .form-label{color:var(--sgds-form-color-default);font-size:var(--sgds-font-size-2);font-weight:var(--sgds-font-weight-regular)}.checkbox-container{display:flex;flex-direction:column;gap:var(--sgds-form-gap-md)}.checkbox-group-validation-input{display:none}`;
5072
5105
 
5073
5106
  /**
5074
5107
  * @summary CheckboxGroup is the container that group multiple checkboxes under a single question field.
@@ -5078,10 +5111,9 @@
5078
5111
  * @slot invalidIcon - The slot for invalid icon
5079
5112
  *
5080
5113
  */
5081
- class SgdsCheckboxGroup extends SgdsElement {
5114
+ class SgdsCheckboxGroup extends SgdsFormValidatorMixin(FormControlElement) {
5082
5115
  constructor() {
5083
- super();
5084
- this.hasInvalidCheckbox = false;
5116
+ super(...arguments);
5085
5117
  /** The checkbox group's label */
5086
5118
  this.label = "";
5087
5119
  /**Feedback text for error state when validated */
@@ -5090,27 +5122,127 @@
5090
5122
  this.hasFeedback = false;
5091
5123
  /** The checkbox group's hint text */
5092
5124
  this.hintText = "";
5093
- this.addEventListener("sgds-validity-change", (e) => {
5094
- this.hasInvalidCheckbox = e.detail.invalid;
5095
- this.validationMessage = e.detail.validationMessage;
5096
- });
5097
- }
5098
- _checkInvalidState() {
5099
- this.hasInvalidCheckbox = Array.from(this.checkboxes).some(checkbox => checkbox.invalid);
5125
+ /** Makes the checkbox group a required field. Only available for when multiselect is true */
5126
+ this.required = false;
5127
+ /** Consolidates the values of its child checked checkboxes into a single string with semi-colon delimiter. Only available when required is true */
5128
+ this.value = "";
5129
+ this._isTouched = false;
5130
+ /**@internal */
5131
+ this.defaultValue = "";
5100
5132
  }
5101
- /** Overrides hasFeedback from individual SgdsCheckbox */
5102
- _forwardHasFeedback() {
5103
- Array.from(this.checkboxes).forEach(checkbox => (checkbox.hasFeedback = this.hasFeedback));
5133
+ connectedCallback() {
5134
+ super.connectedCallback();
5135
+ this.defaultValue = this.value;
5136
+ this.addEventListener("sgds-check", (e) => {
5137
+ const { value } = e.detail;
5138
+ !this.value.includes(value) && this._addValue(value);
5139
+ });
5140
+ this.addEventListener("sgds-uncheck", (e) => {
5141
+ const { value } = e.detail;
5142
+ this._removeValue(value);
5143
+ });
5144
+ this.addEventListener("sgds-blur", () => {
5145
+ this._isTouched = true;
5146
+ });
5104
5147
  }
5105
5148
  _renderHintText() {
5106
5149
  const hintTextTemplate = html ` <div class="form-text">${this.hintText}</div> `;
5107
5150
  return this.hintText && hintTextTemplate;
5108
5151
  }
5109
- firstUpdated() {
5110
- this._forwardHasFeedback();
5152
+ _addValue(newValue) {
5153
+ const valueArray = this.value ? this.value.split(";") : [];
5154
+ valueArray.push(newValue);
5155
+ this.value = valueArray.join(";");
5156
+ }
5157
+ _removeValue(oldValue) {
5158
+ const valueArray = this.value ? this.value.split(";") : [];
5159
+ const newValueArray = valueArray.filter(v => v !== oldValue);
5160
+ this.value = newValueArray.join(";");
5161
+ }
5162
+ _sanitizeSlot() {
5163
+ const checkboxes = this._checkboxes;
5164
+ checkboxes.forEach(checkbox => {
5165
+ checkbox.checked = this.value.includes(checkbox.value);
5166
+ checkbox.hasFeedback = this.hasFeedback ? "style" : null;
5167
+ if (checkbox.required) {
5168
+ console.error("Checkboxes in a group cannot have required or hasFeedback prop set to true");
5169
+ checkbox.remove();
5170
+ }
5171
+ });
5172
+ this._disabledChildCheckboxes();
5173
+ }
5174
+ _disabledChildCheckboxes() {
5175
+ if (this.disabled) {
5176
+ const checkboxes = this._checkboxes;
5177
+ checkboxes.forEach(checkbox => (checkbox.disabled = this.disabled));
5178
+ }
5179
+ }
5180
+ _handleValueChange() {
5181
+ this.emit("sgds-change");
5182
+ const checkboxes = this._checkboxes;
5183
+ checkboxes.forEach(checkbox => {
5184
+ checkbox.checked = this.value.includes(checkbox.value);
5185
+ });
5186
+ this._updateInputValue();
5187
+ this._updateInvalid();
5188
+ }
5189
+ _handleIsTouched() {
5190
+ if (this._isTouched) {
5191
+ this.invalid = !this.input.checkValidity();
5192
+ this._updateInvalid();
5193
+ }
5194
+ }
5195
+ _updateInvalid() {
5196
+ const checkboxes = this._checkboxes;
5197
+ checkboxes.forEach(ch => (ch.invalid = this.invalid));
5198
+ }
5199
+ /**
5200
+ * Checks for validity. Under the hood, HTMLFormElement's reportValidity method calls this method to check for component's validity state
5201
+ * Note that the native error popup is prevented for SGDS form components by default. Instead the validation message shows up in the feedback container of SgdsInput
5202
+ */
5203
+ reportValidity() {
5204
+ return this._mixinReportValidity();
5205
+ }
5206
+ /**
5207
+ * Checks for validity without any native error popup message
5208
+ */
5209
+ checkValidity() {
5210
+ return this._mixinCheckValidity();
5211
+ }
5212
+ /**
5213
+ * Returns the ValidityState object
5214
+ */
5215
+ get validity() {
5216
+ return this._mixinGetValidity();
5217
+ }
5218
+ /**
5219
+ * Returns the validation message based on the ValidityState
5220
+ */
5221
+ get validationMessage() {
5222
+ return this._mixinGetValidationMessage();
5223
+ }
5224
+ /**
5225
+ * radio requries a custom _mixinResetFormControl as the update of input value
5226
+ * requires to fire a reset event manually
5227
+ * */
5228
+ _mixinResetFormControl() {
5229
+ this.value = this.input.value = this.defaultValue;
5230
+ this._updateInputValue("reset");
5231
+ this._mixinResetValidity(this.input);
5232
+ }
5233
+ /**
5234
+ * when input value is set programatically, need to manually dispatch a change event
5235
+ * In order to prevent race conditions and ensure sequence of events, set input's value here instead of binding to value prop of input
5236
+ */
5237
+ _updateInputValue(eventName = "change") {
5238
+ this.input.value = this.value;
5239
+ this.input.dispatchEvent(new InputEvent(eventName));
5111
5240
  }
5112
- updated() {
5113
- this._checkInvalidState();
5241
+ firstUpdated(changedProperties) {
5242
+ super.firstUpdated(changedProperties);
5243
+ if (this.value) {
5244
+ this._updateInputValue();
5245
+ }
5114
5246
  }
5115
5247
  render() {
5116
5248
  return html `
@@ -5120,9 +5252,21 @@
5120
5252
  ${this._renderHintText()}
5121
5253
  </div>
5122
5254
  <div class="checkbox-container">
5123
- <slot></slot>
5255
+ <slot @slotchange=${this._sanitizeSlot}></slot>
5124
5256
  </div>
5125
- ${this.hasInvalidCheckbox && this.hasFeedback
5257
+ <input
5258
+ type="text"
5259
+ class="checkbox-group-validation-input ${classMap({
5260
+ "is-invalid": this.hasFeedback && this.invalid
5261
+ })}"
5262
+ ?required=${this.required}
5263
+ tabindex="-1"
5264
+ @change=${(e) => {
5265
+ super._mixinHandleChange(e);
5266
+ }}
5267
+ .value=${live(this.value)}
5268
+ />
5269
+ ${this.invalid && this.hasFeedback
5126
5270
  ? html `
5127
5271
  <div class="invalid-feedback-container">
5128
5272
  <slot name="invalidIcon">
@@ -5148,11 +5292,8 @@
5148
5292
  queryAssignedElements({ flatten: true })
5149
5293
  ], SgdsCheckboxGroup.prototype, "checkboxes", void 0);
5150
5294
  __decorate([
5151
- state()
5152
- ], SgdsCheckboxGroup.prototype, "hasInvalidCheckbox", void 0);
5153
- __decorate([
5154
- state()
5155
- ], SgdsCheckboxGroup.prototype, "validationMessage", void 0);
5295
+ queryAsync("slot")
5296
+ ], SgdsCheckboxGroup.prototype, "checkboxesAsync", void 0);
5156
5297
  __decorate([
5157
5298
  property({ reflect: true })
5158
5299
  ], SgdsCheckboxGroup.prototype, "label", void 0);
@@ -5165,6 +5306,30 @@
5165
5306
  __decorate([
5166
5307
  property({ reflect: true })
5167
5308
  ], SgdsCheckboxGroup.prototype, "hintText", void 0);
5309
+ __decorate([
5310
+ property({ type: Boolean, reflect: true })
5311
+ ], SgdsCheckboxGroup.prototype, "required", void 0);
5312
+ __decorate([
5313
+ property({ type: String, reflect: true })
5314
+ ], SgdsCheckboxGroup.prototype, "value", void 0);
5315
+ __decorate([
5316
+ state()
5317
+ ], SgdsCheckboxGroup.prototype, "_isTouched", void 0);
5318
+ __decorate([
5319
+ state()
5320
+ ], SgdsCheckboxGroup.prototype, "defaultValue", void 0);
5321
+ __decorate([
5322
+ queryAssignedElements()
5323
+ ], SgdsCheckboxGroup.prototype, "_checkboxes", void 0);
5324
+ __decorate([
5325
+ watch("value", { waitUntilFirstUpdate: true })
5326
+ ], SgdsCheckboxGroup.prototype, "_handleValueChange", null);
5327
+ __decorate([
5328
+ watch("_isTouched", { waitUntilFirstUpdate: true })
5329
+ ], SgdsCheckboxGroup.prototype, "_handleIsTouched", null);
5330
+ __decorate([
5331
+ watch("invalid", { waitUntilFirstUpdate: true })
5332
+ ], SgdsCheckboxGroup.prototype, "_updateInvalid", null);
5168
5333
 
5169
5334
  /**
5170
5335
  *