@govtechsg/sgds-web-component 3.11.0 → 3.12.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/components/Checkbox/index.umd.min.js +6 -6
  2. package/components/Checkbox/index.umd.min.js.map +1 -1
  3. package/components/ComboBox/index.umd.min.js +240 -240
  4. package/components/ComboBox/index.umd.min.js.map +1 -1
  5. package/components/Datepicker/index.umd.min.js +22 -22
  6. package/components/Datepicker/index.umd.min.js.map +1 -1
  7. package/components/FileUpload/index.umd.min.js +8 -8
  8. package/components/FileUpload/index.umd.min.js.map +1 -1
  9. package/components/Input/index.umd.min.js +14 -14
  10. package/components/Input/index.umd.min.js.map +1 -1
  11. package/components/Input/sgds-input.d.ts +1 -0
  12. package/components/Input/sgds-input.js +1 -4
  13. package/components/Input/sgds-input.js.map +1 -1
  14. package/components/Modal/index.umd.min.js.map +1 -1
  15. package/components/Modal/sgds-modal.d.ts +1 -1
  16. package/components/Modal/sgds-modal.js +1 -1
  17. package/components/Modal/sgds-modal.js.map +1 -1
  18. package/components/QuantityToggle/index.umd.min.js +2 -2
  19. package/components/QuantityToggle/index.umd.min.js.map +1 -1
  20. package/components/Radio/index.umd.min.js +9 -9
  21. package/components/Radio/index.umd.min.js.map +1 -1
  22. package/components/Select/index.umd.min.js +11 -11
  23. package/components/Select/index.umd.min.js.map +1 -1
  24. package/components/Tab/index.umd.min.js.map +1 -1
  25. package/components/Tab/sgds-tab-group.d.ts +2 -2
  26. package/components/Tab/sgds-tab-group.js +2 -2
  27. package/components/Tab/sgds-tab-group.js.map +1 -1
  28. package/components/Textarea/index.umd.min.js +6 -6
  29. package/components/Textarea/index.umd.min.js.map +1 -1
  30. package/components/Textarea/sgds-textarea.d.ts +2 -0
  31. package/components/Textarea/sgds-textarea.js +14 -2
  32. package/components/Textarea/sgds-textarea.js.map +1 -1
  33. package/components/index.umd.min.js +4 -4
  34. package/components/index.umd.min.js.map +1 -1
  35. package/css/fouc.css +2 -2
  36. package/index.umd.min.js +49 -49
  37. package/index.umd.min.js.map +1 -1
  38. package/package.json +1 -1
  39. package/react/components/Input/sgds-input.cjs.js +1 -4
  40. package/react/components/Input/sgds-input.cjs.js.map +1 -1
  41. package/react/components/Input/sgds-input.js +1 -4
  42. package/react/components/Input/sgds-input.js.map +1 -1
  43. package/react/components/Modal/sgds-modal.cjs.js +1 -1
  44. package/react/components/Modal/sgds-modal.cjs.js.map +1 -1
  45. package/react/components/Modal/sgds-modal.js +1 -1
  46. package/react/components/Modal/sgds-modal.js.map +1 -1
  47. package/react/components/Tab/sgds-tab-group.cjs.js +2 -2
  48. package/react/components/Tab/sgds-tab-group.cjs.js.map +1 -1
  49. package/react/components/Tab/sgds-tab-group.js +2 -2
  50. package/react/components/Tab/sgds-tab-group.js.map +1 -1
  51. package/react/components/Textarea/sgds-textarea.cjs.js +14 -2
  52. package/react/components/Textarea/sgds-textarea.cjs.js.map +1 -1
  53. package/react/components/Textarea/sgds-textarea.js +14 -2
  54. package/react/components/Textarea/sgds-textarea.js.map +1 -1
  55. package/react/index.cjs.js +12 -12
  56. package/react/index.d.ts +2 -2
  57. package/react/index.js +2 -2
  58. package/react/utils/inputValidationController.cjs.js +2 -1
  59. package/react/utils/inputValidationController.cjs.js.map +1 -1
  60. package/react/utils/inputValidationController.js +2 -1
  61. package/react/utils/inputValidationController.js.map +1 -1
  62. package/react/utils/validatorMixin.cjs.js +24 -6
  63. package/react/utils/validatorMixin.cjs.js.map +1 -1
  64. package/react/utils/validatorMixin.js +24 -6
  65. package/react/utils/validatorMixin.js.map +1 -1
  66. package/utils/inputValidationController.js +2 -1
  67. package/utils/inputValidationController.js.map +1 -1
  68. package/utils/validatorMixin.js +24 -6
  69. package/utils/validatorMixin.js.map +1 -1
@@ -5,7 +5,8 @@
5
5
  class InputValidationController {
6
6
  constructor(host, options) {
7
7
  (this.host = host).addController(this);
8
- this._internals = this.host.attachInternals();
8
+ // Use the internals from the host if it implements the mixin
9
+ this._internals = host._internals || this.host.attachInternals();
9
10
  this.options = Object.assign({ setInvalid: (host, value) => {
10
11
  host.invalid = value;
11
12
  }, value: (host) => {
@@ -1 +1 @@
1
- {"version":3,"file":"inputValidationController.js","sources":["../../../src/utils/inputValidationController.ts"],"sourcesContent":["import { ReactiveController, ReactiveControllerHost } from \"lit\";\nimport { SgdsFormControl } from \"./formSubmitController\";\nimport { SgdsCheckbox, SgdsInput } from \"../components\";\n\n/**\n * SGDS custom form validation methods and behaviours\n */\nexport class InputValidationController implements ReactiveController {\n host: ReactiveControllerHost & HTMLElement;\n _internals: ElementInternals;\n validationError: keyof ValidityState;\n options: InputValidationControllerOptions;\n\n constructor(host: ReactiveControllerHost & HTMLElement, options?: Partial<InputValidationControllerOptions>) {\n (this.host = host).addController(this);\n this._internals = this.host.attachInternals();\n this.options = {\n setInvalid: (host: SgdsFormControl, value: boolean) => {\n host.invalid = value;\n },\n value: (host: SgdsFormControl) => {\n return host.value;\n },\n input: (host: SgdsFormControl) => host.input,\n ...options\n };\n }\n\n hostConnected(): void {\n this.host.addEventListener(\"invalid\", e => this.handleInvalid(e));\n }\n\n hostDisconnected(): void {\n this.host.removeEventListener(\"invalid\", e => this.handleInvalid(e));\n }\n /**\n * Prevents the native browser error message pop up when reportValidity() called by\n * associated form or the component's reportValidity during constraint validation\n * Sets invalid reactive prop to true\n */\n handleInvalid(e: Event) {\n e.preventDefault();\n this.options.setInvalid(this.host, true);\n }\n\n /**\n * Sets invalid to false when invoked and\n * Updates the ValidityState based on new value, but\n * does not update invalid reactive prop\n * @param e\n */\n handleInput(e: Event) {\n const input = e.target as HTMLInputElement;\n this.options.setInvalid(this.host, false);\n this.validateInput(input);\n }\n /**\n * Validate the input's new value after onChange and\n * update invalid reactive prop\n * @param e\n */\n handleChange(e: Event) {\n const input = e.target as HTMLInputElement;\n this.validateInput(input);\n this.options.setInvalid(this.host, !this.checkValidity());\n }\n\n get form() {\n return this._internals.form;\n }\n\n get validity() {\n return this._internals.validity;\n }\n\n get validationMessage() {\n return this._internals.validationMessage;\n }\n\n get willValidate() {\n return this._internals.willValidate;\n }\n /**\n * Checks the validity and updates the invalid reactive prop of form components\n */\n updateInvalidState() {\n this.options.setInvalid(this.host, !this.checkValidity());\n }\n /**\n * Resets the ValidityState of the control\n */\n resetValidity() {\n return this._internals.setValidity({});\n }\n /**\n * Reports the validity\n */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n /**\n * Reports the validity with a error popup message\n */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n setValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void {\n return this._internals.setValidity(flags, message, anchor);\n }\n /**\n * Sets the form control value into FormData,\n * making the value of control accessible via FormData\n */\n setFormValue() {\n const value = this.options.value(this.host) as string | FormData | File;\n this._internals.setFormValue(value);\n }\n /**\n * Updates the ValidityState of the input in form component at current state\n */\n validateInput(input) {\n /** When the form control is disabled, its always valid */\n if (this.options.input(this.host).disabled) {\n return this._internals.setValidity({});\n }\n // get the validity of the internal <input>\n const validState = input.validity;\n // if the input is invalid, show the correct error\n if (!validState.valid) {\n // loop through the error reasons\n for (const state in validState) {\n // if there is an error and corresponding attribute holding\n // the message\n if (validState[state]) {\n this.validationError = state.toString() as keyof ValidityState;\n // set the validity error reason and the corresponding\n // message\n this._internals.setValidity({ [this.validationError]: true }, input.validationMessage, input);\n }\n }\n } else {\n this._internals.setValidity({});\n }\n }\n}\n\nexport interface InputValidationControllerOptions {\n /** A function that sets the value of host invalid reactive prop */\n setInvalid: (host: ReactiveControllerHost & HTMLElement, value: boolean) => void;\n /** A function that gets the value of host value reactive prop */\n value: (host: ReactiveControllerHost & HTMLElement) => unknown;\n /** A function that gets the input control of host value reactive prop */\n input: (host: ReactiveController & HTMLElement) => HTMLInputElement | SgdsInput | SgdsCheckbox;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inputValidationController.js","sources":["../../../src/utils/inputValidationController.ts"],"sourcesContent":["import { ReactiveController, ReactiveControllerHost } from \"lit\";\nimport { SgdsFormControl } from \"./formSubmitController\";\nimport { SgdsCheckbox, SgdsInput } from \"../components\";\n\ninterface HostWithInternals extends ReactiveControllerHost, HTMLElement {\n _internals?: ElementInternals;\n}\n\n/**\n * SGDS custom form validation methods and behaviours\n */\nexport class InputValidationController implements ReactiveController {\n host: ReactiveControllerHost & HTMLElement;\n _internals: ElementInternals;\n validationError: keyof ValidityState;\n options: InputValidationControllerOptions;\n\n constructor(host: ReactiveControllerHost & HTMLElement, options?: Partial<InputValidationControllerOptions>) {\n (this.host = host).addController(this);\n // Use the internals from the host if it implements the mixin\n this._internals = (host as HostWithInternals)._internals || this.host.attachInternals();\n this.options = {\n setInvalid: (host: SgdsFormControl, value: boolean) => {\n host.invalid = value;\n },\n value: (host: SgdsFormControl) => {\n return host.value;\n },\n input: (host: SgdsFormControl) => host.input,\n ...options\n };\n }\n\n hostConnected(): void {\n this.host.addEventListener(\"invalid\", e => this.handleInvalid(e));\n }\n\n hostDisconnected(): void {\n this.host.removeEventListener(\"invalid\", e => this.handleInvalid(e));\n }\n /**\n * Prevents the native browser error message pop up when reportValidity() called by\n * associated form or the component's reportValidity during constraint validation\n * Sets invalid reactive prop to true\n */\n handleInvalid(e: Event) {\n e.preventDefault();\n this.options.setInvalid(this.host, true);\n }\n\n /**\n * Sets invalid to false when invoked and\n * Updates the ValidityState based on new value, but\n * does not update invalid reactive prop\n * @param e\n */\n handleInput(e: Event) {\n const input = e.target as HTMLInputElement;\n this.options.setInvalid(this.host, false);\n this.validateInput(input);\n }\n /**\n * Validate the input's new value after onChange and\n * update invalid reactive prop\n * @param e\n */\n handleChange(e: Event) {\n const input = e.target as HTMLInputElement;\n this.validateInput(input);\n this.options.setInvalid(this.host, !this.checkValidity());\n }\n\n get form() {\n return this._internals.form;\n }\n\n get validity() {\n return this._internals.validity;\n }\n\n get validationMessage() {\n return this._internals.validationMessage;\n }\n\n get willValidate() {\n return this._internals.willValidate;\n }\n /**\n * Checks the validity and updates the invalid reactive prop of form components\n */\n updateInvalidState() {\n this.options.setInvalid(this.host, !this.checkValidity());\n }\n /**\n * Resets the ValidityState of the control\n */\n resetValidity() {\n return this._internals.setValidity({});\n }\n /**\n * Reports the validity\n */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n /**\n * Reports the validity with a error popup message\n */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n setValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void {\n return this._internals.setValidity(flags, message, anchor);\n }\n /**\n * Sets the form control value into FormData,\n * making the value of control accessible via FormData\n */\n setFormValue() {\n const value = this.options.value(this.host) as string | FormData | File;\n this._internals.setFormValue(value);\n }\n /**\n * Updates the ValidityState of the input in form component at current state\n */\n validateInput(input) {\n /** When the form control is disabled, its always valid */\n if (this.options.input(this.host).disabled) {\n return this._internals.setValidity({});\n }\n // get the validity of the internal <input>\n const validState = input.validity;\n // if the input is invalid, show the correct error\n if (!validState.valid) {\n // loop through the error reasons\n for (const state in validState) {\n // if there is an error and corresponding attribute holding\n // the message\n if (validState[state]) {\n this.validationError = state.toString() as keyof ValidityState;\n // set the validity error reason and the corresponding\n // message\n this._internals.setValidity({ [this.validationError]: true }, input.validationMessage, input);\n }\n }\n } else {\n this._internals.setValidity({});\n }\n }\n}\n\nexport interface InputValidationControllerOptions {\n /** A function that sets the value of host invalid reactive prop */\n setInvalid: (host: ReactiveControllerHost & HTMLElement, value: boolean) => void;\n /** A function that gets the value of host value reactive prop */\n value: (host: ReactiveControllerHost & HTMLElement) => unknown;\n /** A function that gets the input control of host value reactive prop */\n input: (host: ReactiveController & HTMLElement) => HTMLInputElement | SgdsInput | SgdsCheckbox;\n}\n"],"names":[],"mappings":"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"}
@@ -14,9 +14,12 @@ var inputValidationController = require('./inputValidationController.cjs.js');
14
14
  */
15
15
  const SgdsFormValidatorMixin = (superClass) => {
16
16
  class ToBeValidatedElement extends superClass {
17
- constructor() {
18
- super(...arguments);
17
+ // TypeScript requires mixin constructors to have rest parameter of type any[]
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ constructor(...args) {
20
+ super(...args);
19
21
  this._isTouched = false;
22
+ this._internals = this.attachInternals();
20
23
  }
21
24
  connectedCallback() {
22
25
  var _a;
@@ -34,9 +37,9 @@ const SgdsFormValidatorMixin = (superClass) => {
34
37
  (await this.sgdsInput) ||
35
38
  this.shadowRoot.querySelector("textarea") ||
36
39
  (await this.sgdsDatepickerInput);
40
+ this._mixinSetFormValue();
37
41
  if (this._mixinShouldSkipSgdsValidation())
38
42
  return;
39
- this._mixinSetFormValue();
40
43
  this._mixinValidate(this.input);
41
44
  }
42
45
  /**
@@ -63,6 +66,8 @@ const SgdsFormValidatorMixin = (superClass) => {
63
66
  */
64
67
  _mixinHandleChange(e) {
65
68
  this._mixinSetFormValue();
69
+ if (this._mixinShouldSkipSgdsValidation())
70
+ return;
66
71
  this.inputValidationController.handleChange(e);
67
72
  }
68
73
  /**
@@ -72,6 +77,8 @@ const SgdsFormValidatorMixin = (superClass) => {
72
77
  */
73
78
  _mixinHandleInputChange(e) {
74
79
  this._mixinSetFormValue();
80
+ if (this._mixinShouldSkipSgdsValidation())
81
+ return;
75
82
  this.inputValidationController.handleInput(e);
76
83
  }
77
84
  /**
@@ -83,30 +90,41 @@ const SgdsFormValidatorMixin = (superClass) => {
83
90
  * 4. Reset touched state to false for a pristine form
84
91
  */
85
92
  _mixinResetValidity(input) {
93
+ if (this._mixinShouldSkipSgdsValidation())
94
+ return;
86
95
  this.inputValidationController.resetValidity();
87
96
  this.inputValidationController.updateInvalidState();
88
97
  this.inputValidationController.validateInput(input);
89
98
  this._isTouched ? (this._isTouched = false) : null;
90
99
  }
91
100
  _mixinValidate(input) {
101
+ if (this._mixinShouldSkipSgdsValidation())
102
+ return;
92
103
  this.inputValidationController.validateInput(input);
93
104
  }
94
105
  _mixinSetFormValue() {
95
- this.inputValidationController.setFormValue();
106
+ const value = this.value;
107
+ this._internals.setFormValue(value);
96
108
  }
97
109
  _mixinCheckValidity() {
110
+ if (this._mixinShouldSkipSgdsValidation())
111
+ return true;
98
112
  return this.inputValidationController.checkValidity();
99
113
  }
100
114
  _mixinReportValidity() {
115
+ if (this._mixinShouldSkipSgdsValidation())
116
+ return true;
101
117
  return this.inputValidationController.reportValidity();
102
118
  }
103
119
  _mixinGetValidity() {
104
- return this.inputValidationController.validity;
120
+ return this._internals.validity;
105
121
  }
106
122
  _mixinGetValidationMessage() {
107
- return this.inputValidationController.validationMessage;
123
+ return this._internals.validationMessage;
108
124
  }
109
125
  _mixinSetValidity(flags, message, anchor) {
126
+ if (this._mixinShouldSkipSgdsValidation())
127
+ return;
110
128
  return this.inputValidationController.setValidity(flags, message, anchor);
111
129
  }
112
130
  // Only check for noValidate prop
@@ -1 +1 @@
1
- {"version":3,"file":"validatorMixin.cjs.js","sources":["../../../src/utils/validatorMixin.ts"],"sourcesContent":["import { LitElement, PropertyValueMap } from \"lit\";\nimport { queryAsync } from \"lit/decorators.js\";\nimport { SgdsInput } from \"../components\";\nimport { InputValidationController } from \"./inputValidationController\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Constructor<T> = new (...args: any[]) => T;\n\n/**\n * @summary The FormValidationMixin used by the form components\n * @param superClass\n * @returns\n */\nexport const SgdsFormValidatorMixin = <T extends Constructor<LitElement>>(superClass: T) => {\n class ToBeValidatedElement extends superClass {\n static formAssociated = true;\n inputValidationController: InputValidationController;\n input: HTMLInputElement | SgdsInput | HTMLTextAreaElement;\n private _isTouched = false;\n @queryAsync(\"sgds-input\") sgdsInput: Promise<SgdsInput>;\n @queryAsync(\"sgds-datepicker-input\") sgdsDatepickerInput: Promise<SgdsInput>;\n\n connectedCallback(): void {\n super.connectedCallback();\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n /** Idempotency guarantee */\n this.inputValidationController ??= new InputValidationController(this);\n }\n async firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n\n /* Either input or sgds-input. For example, quantity-toggle uses sgds-input */\n this.input =\n this.shadowRoot.querySelector(\"input\") ||\n (await this.sgdsInput) ||\n this.shadowRoot.querySelector(\"textarea\") ||\n (await this.sgdsDatepickerInput);\n\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n this._mixinSetFormValue();\n\n this._mixinValidate(this.input);\n }\n\n /**\n * Native lifecycle of Form-Associated Custom Element Callbacks\n */\n formResetCallback() {\n if (this._mixinResetFormControl) {\n this._mixinResetFormControl();\n } else {\n this.value = this.defaultValue;\n this._mixinResetValidity(this.input);\n }\n this._mixinSetFormValue();\n }\n /**\n *\n * Methods use by classes using this mixin\n */\n\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run change handler\n */\n _mixinHandleChange(e: Event): void {\n this._mixinSetFormValue();\n this.inputValidationController.handleChange(e);\n }\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run input handler\n */\n _mixinHandleInputChange(e: Event): void {\n this._mixinSetFormValue();\n this.inputValidationController.handleInput(e);\n }\n /**\n * During form resetting,\n * 1. ValidityState is reset\n * 2. invalid reactive prop is updated after the reset\n * 3. Revalidates the ValidityState (but do not update invalid prop)\n * to prepare for the next validity check\n * 4. Reset touched state to false for a pristine form\n */\n _mixinResetValidity(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n this.inputValidationController.resetValidity();\n this.inputValidationController.updateInvalidState();\n this.inputValidationController.validateInput(input);\n this._isTouched ? (this._isTouched = false) : null;\n }\n\n _mixinValidate(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n this.inputValidationController.validateInput(input);\n }\n _mixinSetFormValue() {\n this.inputValidationController.setFormValue();\n }\n _mixinCheckValidity(): boolean {\n return this.inputValidationController.checkValidity();\n }\n _mixinReportValidity(): boolean {\n return this.inputValidationController.reportValidity();\n }\n _mixinGetValidity(): ValidityState {\n return this.inputValidationController.validity;\n }\n _mixinGetValidationMessage(): string {\n return this.inputValidationController.validationMessage;\n }\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void {\n return this.inputValidationController.setValidity(flags, message, anchor);\n }\n // Only check for noValidate prop\n _mixinShouldSkipSgdsValidation() {\n const form = this.closest(\"form\");\n\n return form?.noValidate || this.noValidate;\n }\n\n /** DECLARED INSTANCE METHODS AND PROPERTIES*/\n\n /**\n * Resets a form control to its initial state\n */\n declare _mixinResetFormControl: () => void;\n declare value: string;\n declare defaultValue: string;\n declare defaultChecked: boolean;\n declare noValidate: boolean;\n }\n\n return ToBeValidatedElement as Constructor<ToBeValidatedElementInterface> & T;\n};\n\nexport declare class ToBeValidatedElementInterface {\n inputValidationController: InputValidationController;\n input: HTMLInputElement;\n _mixinHandleChange(e: Event): void;\n _mixinHandleInputChange(e: Event): void;\n _mixinResetValidity(input: HTMLInputElement | SgdsInput): void;\n _mixinValidate(input: HTMLInputElement | SgdsInput): void;\n _mixinSetFormValue(): void;\n _mixinCheckValidity(): boolean;\n _mixinReportValidity(): boolean;\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void;\n _mixinGetValidity(): ValidityState;\n _mixinGetValidationMessage(): string;\n _mixinShouldSkipSgdsValidation(): boolean;\n}\n"],"names":["InputValidationController","__decorate","queryAsync"],"mappings":"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"}
1
+ {"version":3,"file":"validatorMixin.cjs.js","sources":["../../../src/utils/validatorMixin.ts"],"sourcesContent":["import { LitElement, PropertyValueMap } from \"lit\";\nimport { queryAsync } from \"lit/decorators.js\";\nimport { SgdsInput } from \"../components\";\nimport { InputValidationController } from \"./inputValidationController\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Constructor<T> = new (...args: any[]) => T;\n\n/**\n * @summary The FormValidationMixin used by the form components\n * @param superClass\n * @returns\n */\nexport const SgdsFormValidatorMixin = <T extends Constructor<LitElement>>(superClass: T) => {\n class ToBeValidatedElement extends superClass {\n static formAssociated = true;\n inputValidationController: InputValidationController;\n input: HTMLInputElement | SgdsInput | HTMLTextAreaElement;\n private _isTouched = false;\n private _internals: ElementInternals;\n @queryAsync(\"sgds-input\") sgdsInput: Promise<SgdsInput>;\n @queryAsync(\"sgds-datepicker-input\") sgdsDatepickerInput: Promise<SgdsInput>;\n\n // TypeScript requires mixin constructors to have rest parameter of type any[]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(...args: any[]) {\n super(...args);\n this._internals = this.attachInternals();\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n /** Idempotency guarantee */\n this.inputValidationController ??= new InputValidationController(this);\n }\n async firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n\n /* Either input or sgds-input. For example, quantity-toggle uses sgds-input */\n this.input =\n this.shadowRoot.querySelector(\"input\") ||\n (await this.sgdsInput) ||\n this.shadowRoot.querySelector(\"textarea\") ||\n (await this.sgdsDatepickerInput);\n\n this._mixinSetFormValue();\n\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n this._mixinValidate(this.input);\n }\n\n /**\n * Native lifecycle of Form-Associated Custom Element Callbacks\n */\n formResetCallback() {\n if (this._mixinResetFormControl) {\n this._mixinResetFormControl();\n } else {\n this.value = this.defaultValue;\n this._mixinResetValidity(this.input);\n }\n this._mixinSetFormValue();\n }\n /**\n *\n * Methods use by classes using this mixin\n */\n\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run change handler\n */\n _mixinHandleChange(e: Event): void {\n this._mixinSetFormValue();\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.handleChange(e);\n }\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run input handler\n */\n _mixinHandleInputChange(e: Event): void {\n this._mixinSetFormValue();\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.handleInput(e);\n }\n /**\n * During form resetting,\n * 1. ValidityState is reset\n * 2. invalid reactive prop is updated after the reset\n * 3. Revalidates the ValidityState (but do not update invalid prop)\n * to prepare for the next validity check\n * 4. Reset touched state to false for a pristine form\n */\n _mixinResetValidity(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.resetValidity();\n this.inputValidationController.updateInvalidState();\n this.inputValidationController.validateInput(input);\n this._isTouched ? (this._isTouched = false) : null;\n }\n\n _mixinValidate(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.validateInput(input);\n }\n _mixinSetFormValue() {\n const value = this.value as string | FormData | File;\n this._internals.setFormValue(value);\n }\n _mixinCheckValidity(): boolean {\n if (this._mixinShouldSkipSgdsValidation()) return true;\n return this.inputValidationController.checkValidity();\n }\n _mixinReportValidity(): boolean {\n if (this._mixinShouldSkipSgdsValidation()) return true;\n return this.inputValidationController.reportValidity();\n }\n _mixinGetValidity(): ValidityState {\n return this._internals.validity;\n }\n _mixinGetValidationMessage(): string {\n return this._internals.validationMessage;\n }\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void {\n if (this._mixinShouldSkipSgdsValidation()) return;\n return this.inputValidationController.setValidity(flags, message, anchor);\n }\n // Only check for noValidate prop\n _mixinShouldSkipSgdsValidation() {\n const form = this.closest(\"form\");\n\n return form?.noValidate || this.noValidate;\n }\n\n /** DECLARED INSTANCE METHODS AND PROPERTIES*/\n\n /**\n * Resets a form control to its initial state\n */\n declare _mixinResetFormControl: () => void;\n declare value: string;\n declare defaultValue: string;\n declare defaultChecked: boolean;\n declare noValidate: boolean;\n }\n\n return ToBeValidatedElement as Constructor<ToBeValidatedElementInterface> & T;\n};\n\nexport declare class ToBeValidatedElementInterface {\n inputValidationController: InputValidationController;\n input: HTMLInputElement;\n _mixinHandleChange(e: Event): void;\n _mixinHandleInputChange(e: Event): void;\n _mixinResetValidity(input: HTMLInputElement | SgdsInput): void;\n _mixinValidate(input: HTMLInputElement | SgdsInput): void;\n _mixinSetFormValue(): void;\n _mixinCheckValidity(): boolean;\n _mixinReportValidity(): boolean;\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void;\n _mixinGetValidity(): ValidityState;\n _mixinGetValidationMessage(): string;\n _mixinShouldSkipSgdsValidation(): boolean;\n}\n"],"names":["InputValidationController","__decorate","queryAsync"],"mappings":"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"}
@@ -10,9 +10,12 @@ import { InputValidationController } from './inputValidationController.js';
10
10
  */
11
11
  const SgdsFormValidatorMixin = (superClass) => {
12
12
  class ToBeValidatedElement extends superClass {
13
- constructor() {
14
- super(...arguments);
13
+ // TypeScript requires mixin constructors to have rest parameter of type any[]
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ constructor(...args) {
16
+ super(...args);
15
17
  this._isTouched = false;
18
+ this._internals = this.attachInternals();
16
19
  }
17
20
  connectedCallback() {
18
21
  var _a;
@@ -30,9 +33,9 @@ const SgdsFormValidatorMixin = (superClass) => {
30
33
  (await this.sgdsInput) ||
31
34
  this.shadowRoot.querySelector("textarea") ||
32
35
  (await this.sgdsDatepickerInput);
36
+ this._mixinSetFormValue();
33
37
  if (this._mixinShouldSkipSgdsValidation())
34
38
  return;
35
- this._mixinSetFormValue();
36
39
  this._mixinValidate(this.input);
37
40
  }
38
41
  /**
@@ -59,6 +62,8 @@ const SgdsFormValidatorMixin = (superClass) => {
59
62
  */
60
63
  _mixinHandleChange(e) {
61
64
  this._mixinSetFormValue();
65
+ if (this._mixinShouldSkipSgdsValidation())
66
+ return;
62
67
  this.inputValidationController.handleChange(e);
63
68
  }
64
69
  /**
@@ -68,6 +73,8 @@ const SgdsFormValidatorMixin = (superClass) => {
68
73
  */
69
74
  _mixinHandleInputChange(e) {
70
75
  this._mixinSetFormValue();
76
+ if (this._mixinShouldSkipSgdsValidation())
77
+ return;
71
78
  this.inputValidationController.handleInput(e);
72
79
  }
73
80
  /**
@@ -79,30 +86,41 @@ const SgdsFormValidatorMixin = (superClass) => {
79
86
  * 4. Reset touched state to false for a pristine form
80
87
  */
81
88
  _mixinResetValidity(input) {
89
+ if (this._mixinShouldSkipSgdsValidation())
90
+ return;
82
91
  this.inputValidationController.resetValidity();
83
92
  this.inputValidationController.updateInvalidState();
84
93
  this.inputValidationController.validateInput(input);
85
94
  this._isTouched ? (this._isTouched = false) : null;
86
95
  }
87
96
  _mixinValidate(input) {
97
+ if (this._mixinShouldSkipSgdsValidation())
98
+ return;
88
99
  this.inputValidationController.validateInput(input);
89
100
  }
90
101
  _mixinSetFormValue() {
91
- this.inputValidationController.setFormValue();
102
+ const value = this.value;
103
+ this._internals.setFormValue(value);
92
104
  }
93
105
  _mixinCheckValidity() {
106
+ if (this._mixinShouldSkipSgdsValidation())
107
+ return true;
94
108
  return this.inputValidationController.checkValidity();
95
109
  }
96
110
  _mixinReportValidity() {
111
+ if (this._mixinShouldSkipSgdsValidation())
112
+ return true;
97
113
  return this.inputValidationController.reportValidity();
98
114
  }
99
115
  _mixinGetValidity() {
100
- return this.inputValidationController.validity;
116
+ return this._internals.validity;
101
117
  }
102
118
  _mixinGetValidationMessage() {
103
- return this.inputValidationController.validationMessage;
119
+ return this._internals.validationMessage;
104
120
  }
105
121
  _mixinSetValidity(flags, message, anchor) {
122
+ if (this._mixinShouldSkipSgdsValidation())
123
+ return;
106
124
  return this.inputValidationController.setValidity(flags, message, anchor);
107
125
  }
108
126
  // Only check for noValidate prop
@@ -1 +1 @@
1
- {"version":3,"file":"validatorMixin.js","sources":["../../../src/utils/validatorMixin.ts"],"sourcesContent":["import { LitElement, PropertyValueMap } from \"lit\";\nimport { queryAsync } from \"lit/decorators.js\";\nimport { SgdsInput } from \"../components\";\nimport { InputValidationController } from \"./inputValidationController\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Constructor<T> = new (...args: any[]) => T;\n\n/**\n * @summary The FormValidationMixin used by the form components\n * @param superClass\n * @returns\n */\nexport const SgdsFormValidatorMixin = <T extends Constructor<LitElement>>(superClass: T) => {\n class ToBeValidatedElement extends superClass {\n static formAssociated = true;\n inputValidationController: InputValidationController;\n input: HTMLInputElement | SgdsInput | HTMLTextAreaElement;\n private _isTouched = false;\n @queryAsync(\"sgds-input\") sgdsInput: Promise<SgdsInput>;\n @queryAsync(\"sgds-datepicker-input\") sgdsDatepickerInput: Promise<SgdsInput>;\n\n connectedCallback(): void {\n super.connectedCallback();\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n /** Idempotency guarantee */\n this.inputValidationController ??= new InputValidationController(this);\n }\n async firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n\n /* Either input or sgds-input. For example, quantity-toggle uses sgds-input */\n this.input =\n this.shadowRoot.querySelector(\"input\") ||\n (await this.sgdsInput) ||\n this.shadowRoot.querySelector(\"textarea\") ||\n (await this.sgdsDatepickerInput);\n\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n this._mixinSetFormValue();\n\n this._mixinValidate(this.input);\n }\n\n /**\n * Native lifecycle of Form-Associated Custom Element Callbacks\n */\n formResetCallback() {\n if (this._mixinResetFormControl) {\n this._mixinResetFormControl();\n } else {\n this.value = this.defaultValue;\n this._mixinResetValidity(this.input);\n }\n this._mixinSetFormValue();\n }\n /**\n *\n * Methods use by classes using this mixin\n */\n\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run change handler\n */\n _mixinHandleChange(e: Event): void {\n this._mixinSetFormValue();\n this.inputValidationController.handleChange(e);\n }\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run input handler\n */\n _mixinHandleInputChange(e: Event): void {\n this._mixinSetFormValue();\n this.inputValidationController.handleInput(e);\n }\n /**\n * During form resetting,\n * 1. ValidityState is reset\n * 2. invalid reactive prop is updated after the reset\n * 3. Revalidates the ValidityState (but do not update invalid prop)\n * to prepare for the next validity check\n * 4. Reset touched state to false for a pristine form\n */\n _mixinResetValidity(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n this.inputValidationController.resetValidity();\n this.inputValidationController.updateInvalidState();\n this.inputValidationController.validateInput(input);\n this._isTouched ? (this._isTouched = false) : null;\n }\n\n _mixinValidate(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n this.inputValidationController.validateInput(input);\n }\n _mixinSetFormValue() {\n this.inputValidationController.setFormValue();\n }\n _mixinCheckValidity(): boolean {\n return this.inputValidationController.checkValidity();\n }\n _mixinReportValidity(): boolean {\n return this.inputValidationController.reportValidity();\n }\n _mixinGetValidity(): ValidityState {\n return this.inputValidationController.validity;\n }\n _mixinGetValidationMessage(): string {\n return this.inputValidationController.validationMessage;\n }\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void {\n return this.inputValidationController.setValidity(flags, message, anchor);\n }\n // Only check for noValidate prop\n _mixinShouldSkipSgdsValidation() {\n const form = this.closest(\"form\");\n\n return form?.noValidate || this.noValidate;\n }\n\n /** DECLARED INSTANCE METHODS AND PROPERTIES*/\n\n /**\n * Resets a form control to its initial state\n */\n declare _mixinResetFormControl: () => void;\n declare value: string;\n declare defaultValue: string;\n declare defaultChecked: boolean;\n declare noValidate: boolean;\n }\n\n return ToBeValidatedElement as Constructor<ToBeValidatedElementInterface> & T;\n};\n\nexport declare class ToBeValidatedElementInterface {\n inputValidationController: InputValidationController;\n input: HTMLInputElement;\n _mixinHandleChange(e: Event): void;\n _mixinHandleInputChange(e: Event): void;\n _mixinResetValidity(input: HTMLInputElement | SgdsInput): void;\n _mixinValidate(input: HTMLInputElement | SgdsInput): void;\n _mixinSetFormValue(): void;\n _mixinCheckValidity(): boolean;\n _mixinReportValidity(): boolean;\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void;\n _mixinGetValidity(): ValidityState;\n _mixinGetValidationMessage(): string;\n _mixinShouldSkipSgdsValidation(): boolean;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validatorMixin.js","sources":["../../../src/utils/validatorMixin.ts"],"sourcesContent":["import { LitElement, PropertyValueMap } from \"lit\";\nimport { queryAsync } from \"lit/decorators.js\";\nimport { SgdsInput } from \"../components\";\nimport { InputValidationController } from \"./inputValidationController\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Constructor<T> = new (...args: any[]) => T;\n\n/**\n * @summary The FormValidationMixin used by the form components\n * @param superClass\n * @returns\n */\nexport const SgdsFormValidatorMixin = <T extends Constructor<LitElement>>(superClass: T) => {\n class ToBeValidatedElement extends superClass {\n static formAssociated = true;\n inputValidationController: InputValidationController;\n input: HTMLInputElement | SgdsInput | HTMLTextAreaElement;\n private _isTouched = false;\n private _internals: ElementInternals;\n @queryAsync(\"sgds-input\") sgdsInput: Promise<SgdsInput>;\n @queryAsync(\"sgds-datepicker-input\") sgdsDatepickerInput: Promise<SgdsInput>;\n\n // TypeScript requires mixin constructors to have rest parameter of type any[]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(...args: any[]) {\n super(...args);\n this._internals = this.attachInternals();\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n /** Idempotency guarantee */\n this.inputValidationController ??= new InputValidationController(this);\n }\n async firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n\n /* Either input or sgds-input. For example, quantity-toggle uses sgds-input */\n this.input =\n this.shadowRoot.querySelector(\"input\") ||\n (await this.sgdsInput) ||\n this.shadowRoot.querySelector(\"textarea\") ||\n (await this.sgdsDatepickerInput);\n\n this._mixinSetFormValue();\n\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n this._mixinValidate(this.input);\n }\n\n /**\n * Native lifecycle of Form-Associated Custom Element Callbacks\n */\n formResetCallback() {\n if (this._mixinResetFormControl) {\n this._mixinResetFormControl();\n } else {\n this.value = this.defaultValue;\n this._mixinResetValidity(this.input);\n }\n this._mixinSetFormValue();\n }\n /**\n *\n * Methods use by classes using this mixin\n */\n\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run change handler\n */\n _mixinHandleChange(e: Event): void {\n this._mixinSetFormValue();\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.handleChange(e);\n }\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run input handler\n */\n _mixinHandleInputChange(e: Event): void {\n this._mixinSetFormValue();\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.handleInput(e);\n }\n /**\n * During form resetting,\n * 1. ValidityState is reset\n * 2. invalid reactive prop is updated after the reset\n * 3. Revalidates the ValidityState (but do not update invalid prop)\n * to prepare for the next validity check\n * 4. Reset touched state to false for a pristine form\n */\n _mixinResetValidity(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.resetValidity();\n this.inputValidationController.updateInvalidState();\n this.inputValidationController.validateInput(input);\n this._isTouched ? (this._isTouched = false) : null;\n }\n\n _mixinValidate(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.validateInput(input);\n }\n _mixinSetFormValue() {\n const value = this.value as string | FormData | File;\n this._internals.setFormValue(value);\n }\n _mixinCheckValidity(): boolean {\n if (this._mixinShouldSkipSgdsValidation()) return true;\n return this.inputValidationController.checkValidity();\n }\n _mixinReportValidity(): boolean {\n if (this._mixinShouldSkipSgdsValidation()) return true;\n return this.inputValidationController.reportValidity();\n }\n _mixinGetValidity(): ValidityState {\n return this._internals.validity;\n }\n _mixinGetValidationMessage(): string {\n return this._internals.validationMessage;\n }\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void {\n if (this._mixinShouldSkipSgdsValidation()) return;\n return this.inputValidationController.setValidity(flags, message, anchor);\n }\n // Only check for noValidate prop\n _mixinShouldSkipSgdsValidation() {\n const form = this.closest(\"form\");\n\n return form?.noValidate || this.noValidate;\n }\n\n /** DECLARED INSTANCE METHODS AND PROPERTIES*/\n\n /**\n * Resets a form control to its initial state\n */\n declare _mixinResetFormControl: () => void;\n declare value: string;\n declare defaultValue: string;\n declare defaultChecked: boolean;\n declare noValidate: boolean;\n }\n\n return ToBeValidatedElement as Constructor<ToBeValidatedElementInterface> & T;\n};\n\nexport declare class ToBeValidatedElementInterface {\n inputValidationController: InputValidationController;\n input: HTMLInputElement;\n _mixinHandleChange(e: Event): void;\n _mixinHandleInputChange(e: Event): void;\n _mixinResetValidity(input: HTMLInputElement | SgdsInput): void;\n _mixinValidate(input: HTMLInputElement | SgdsInput): void;\n _mixinSetFormValue(): void;\n _mixinCheckValidity(): boolean;\n _mixinReportValidity(): boolean;\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void;\n _mixinGetValidity(): ValidityState;\n _mixinGetValidationMessage(): string;\n _mixinShouldSkipSgdsValidation(): boolean;\n}\n"],"names":[],"mappings":"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"}
@@ -4,7 +4,8 @@
4
4
  class InputValidationController {
5
5
  constructor(host, options) {
6
6
  (this.host = host).addController(this);
7
- this._internals = this.host.attachInternals();
7
+ // Use the internals from the host if it implements the mixin
8
+ this._internals = host._internals || this.host.attachInternals();
8
9
  this.options = Object.assign({ setInvalid: (host, value) => {
9
10
  host.invalid = value;
10
11
  }, value: (host) => {
@@ -1 +1 @@
1
- {"version":3,"file":"inputValidationController.js","sources":["../../src/utils/inputValidationController.ts"],"sourcesContent":["import { ReactiveController, ReactiveControllerHost } from \"lit\";\nimport { SgdsFormControl } from \"./formSubmitController\";\nimport { SgdsCheckbox, SgdsInput } from \"../components\";\n\n/**\n * SGDS custom form validation methods and behaviours\n */\nexport class InputValidationController implements ReactiveController {\n host: ReactiveControllerHost & HTMLElement;\n _internals: ElementInternals;\n validationError: keyof ValidityState;\n options: InputValidationControllerOptions;\n\n constructor(host: ReactiveControllerHost & HTMLElement, options?: Partial<InputValidationControllerOptions>) {\n (this.host = host).addController(this);\n this._internals = this.host.attachInternals();\n this.options = {\n setInvalid: (host: SgdsFormControl, value: boolean) => {\n host.invalid = value;\n },\n value: (host: SgdsFormControl) => {\n return host.value;\n },\n input: (host: SgdsFormControl) => host.input,\n ...options\n };\n }\n\n hostConnected(): void {\n this.host.addEventListener(\"invalid\", e => this.handleInvalid(e));\n }\n\n hostDisconnected(): void {\n this.host.removeEventListener(\"invalid\", e => this.handleInvalid(e));\n }\n /**\n * Prevents the native browser error message pop up when reportValidity() called by\n * associated form or the component's reportValidity during constraint validation\n * Sets invalid reactive prop to true\n */\n handleInvalid(e: Event) {\n e.preventDefault();\n this.options.setInvalid(this.host, true);\n }\n\n /**\n * Sets invalid to false when invoked and\n * Updates the ValidityState based on new value, but\n * does not update invalid reactive prop\n * @param e\n */\n handleInput(e: Event) {\n const input = e.target as HTMLInputElement;\n this.options.setInvalid(this.host, false);\n this.validateInput(input);\n }\n /**\n * Validate the input's new value after onChange and\n * update invalid reactive prop\n * @param e\n */\n handleChange(e: Event) {\n const input = e.target as HTMLInputElement;\n this.validateInput(input);\n this.options.setInvalid(this.host, !this.checkValidity());\n }\n\n get form() {\n return this._internals.form;\n }\n\n get validity() {\n return this._internals.validity;\n }\n\n get validationMessage() {\n return this._internals.validationMessage;\n }\n\n get willValidate() {\n return this._internals.willValidate;\n }\n /**\n * Checks the validity and updates the invalid reactive prop of form components\n */\n updateInvalidState() {\n this.options.setInvalid(this.host, !this.checkValidity());\n }\n /**\n * Resets the ValidityState of the control\n */\n resetValidity() {\n return this._internals.setValidity({});\n }\n /**\n * Reports the validity\n */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n /**\n * Reports the validity with a error popup message\n */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n setValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void {\n return this._internals.setValidity(flags, message, anchor);\n }\n /**\n * Sets the form control value into FormData,\n * making the value of control accessible via FormData\n */\n setFormValue() {\n const value = this.options.value(this.host) as string | FormData | File;\n this._internals.setFormValue(value);\n }\n /**\n * Updates the ValidityState of the input in form component at current state\n */\n validateInput(input) {\n /** When the form control is disabled, its always valid */\n if (this.options.input(this.host).disabled) {\n return this._internals.setValidity({});\n }\n // get the validity of the internal <input>\n const validState = input.validity;\n // if the input is invalid, show the correct error\n if (!validState.valid) {\n // loop through the error reasons\n for (const state in validState) {\n // if there is an error and corresponding attribute holding\n // the message\n if (validState[state]) {\n this.validationError = state.toString() as keyof ValidityState;\n // set the validity error reason and the corresponding\n // message\n this._internals.setValidity({ [this.validationError]: true }, input.validationMessage, input);\n }\n }\n } else {\n this._internals.setValidity({});\n }\n }\n}\n\nexport interface InputValidationControllerOptions {\n /** A function that sets the value of host invalid reactive prop */\n setInvalid: (host: ReactiveControllerHost & HTMLElement, value: boolean) => void;\n /** A function that gets the value of host value reactive prop */\n value: (host: ReactiveControllerHost & HTMLElement) => unknown;\n /** A function that gets the input control of host value reactive prop */\n input: (host: ReactiveController & HTMLElement) => HTMLInputElement | SgdsInput | SgdsCheckbox;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inputValidationController.js","sources":["../../src/utils/inputValidationController.ts"],"sourcesContent":["import { ReactiveController, ReactiveControllerHost } from \"lit\";\nimport { SgdsFormControl } from \"./formSubmitController\";\nimport { SgdsCheckbox, SgdsInput } from \"../components\";\n\ninterface HostWithInternals extends ReactiveControllerHost, HTMLElement {\n _internals?: ElementInternals;\n}\n\n/**\n * SGDS custom form validation methods and behaviours\n */\nexport class InputValidationController implements ReactiveController {\n host: ReactiveControllerHost & HTMLElement;\n _internals: ElementInternals;\n validationError: keyof ValidityState;\n options: InputValidationControllerOptions;\n\n constructor(host: ReactiveControllerHost & HTMLElement, options?: Partial<InputValidationControllerOptions>) {\n (this.host = host).addController(this);\n // Use the internals from the host if it implements the mixin\n this._internals = (host as HostWithInternals)._internals || this.host.attachInternals();\n this.options = {\n setInvalid: (host: SgdsFormControl, value: boolean) => {\n host.invalid = value;\n },\n value: (host: SgdsFormControl) => {\n return host.value;\n },\n input: (host: SgdsFormControl) => host.input,\n ...options\n };\n }\n\n hostConnected(): void {\n this.host.addEventListener(\"invalid\", e => this.handleInvalid(e));\n }\n\n hostDisconnected(): void {\n this.host.removeEventListener(\"invalid\", e => this.handleInvalid(e));\n }\n /**\n * Prevents the native browser error message pop up when reportValidity() called by\n * associated form or the component's reportValidity during constraint validation\n * Sets invalid reactive prop to true\n */\n handleInvalid(e: Event) {\n e.preventDefault();\n this.options.setInvalid(this.host, true);\n }\n\n /**\n * Sets invalid to false when invoked and\n * Updates the ValidityState based on new value, but\n * does not update invalid reactive prop\n * @param e\n */\n handleInput(e: Event) {\n const input = e.target as HTMLInputElement;\n this.options.setInvalid(this.host, false);\n this.validateInput(input);\n }\n /**\n * Validate the input's new value after onChange and\n * update invalid reactive prop\n * @param e\n */\n handleChange(e: Event) {\n const input = e.target as HTMLInputElement;\n this.validateInput(input);\n this.options.setInvalid(this.host, !this.checkValidity());\n }\n\n get form() {\n return this._internals.form;\n }\n\n get validity() {\n return this._internals.validity;\n }\n\n get validationMessage() {\n return this._internals.validationMessage;\n }\n\n get willValidate() {\n return this._internals.willValidate;\n }\n /**\n * Checks the validity and updates the invalid reactive prop of form components\n */\n updateInvalidState() {\n this.options.setInvalid(this.host, !this.checkValidity());\n }\n /**\n * Resets the ValidityState of the control\n */\n resetValidity() {\n return this._internals.setValidity({});\n }\n /**\n * Reports the validity\n */\n checkValidity(): boolean {\n return this._internals.checkValidity();\n }\n /**\n * Reports the validity with a error popup message\n */\n reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n setValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void {\n return this._internals.setValidity(flags, message, anchor);\n }\n /**\n * Sets the form control value into FormData,\n * making the value of control accessible via FormData\n */\n setFormValue() {\n const value = this.options.value(this.host) as string | FormData | File;\n this._internals.setFormValue(value);\n }\n /**\n * Updates the ValidityState of the input in form component at current state\n */\n validateInput(input) {\n /** When the form control is disabled, its always valid */\n if (this.options.input(this.host).disabled) {\n return this._internals.setValidity({});\n }\n // get the validity of the internal <input>\n const validState = input.validity;\n // if the input is invalid, show the correct error\n if (!validState.valid) {\n // loop through the error reasons\n for (const state in validState) {\n // if there is an error and corresponding attribute holding\n // the message\n if (validState[state]) {\n this.validationError = state.toString() as keyof ValidityState;\n // set the validity error reason and the corresponding\n // message\n this._internals.setValidity({ [this.validationError]: true }, input.validationMessage, input);\n }\n }\n } else {\n this._internals.setValidity({});\n }\n }\n}\n\nexport interface InputValidationControllerOptions {\n /** A function that sets the value of host invalid reactive prop */\n setInvalid: (host: ReactiveControllerHost & HTMLElement, value: boolean) => void;\n /** A function that gets the value of host value reactive prop */\n value: (host: ReactiveControllerHost & HTMLElement) => unknown;\n /** A function that gets the input control of host value reactive prop */\n input: (host: ReactiveController & HTMLElement) => HTMLInputElement | SgdsInput | SgdsCheckbox;\n}\n"],"names":[],"mappings":"AAQA;;AAEG;MACU,yBAAyB,CAAA;IAMpC,WAAY,CAAA,IAA0C,EAAE,OAAmD,EAAA;QACzG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;;AAEvC,QAAA,IAAI,CAAC,UAAU,GAAI,IAA0B,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;QACxF,IAAI,CAAC,OAAO,GAAA,MAAA,CAAA,MAAA,CAAA,EACV,UAAU,EAAE,CAAC,IAAqB,EAAE,KAAc,KAAI;AACpD,gBAAA,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;AACvB,aAAC,EACD,KAAK,EAAE,CAAC,IAAqB,KAAI;gBAC/B,OAAO,IAAI,CAAC,KAAK,CAAC;AACpB,aAAC,EACD,KAAK,EAAE,CAAC,IAAqB,KAAK,IAAI,CAAC,KAAK,EACzC,EAAA,OAAO,CACX,CAAC;KACH;IAED,aAAa,GAAA;AACX,QAAA,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;KACnE;IAED,gBAAgB,GAAA;AACd,QAAA,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;KACtE;AACD;;;;AAIG;AACH,IAAA,aAAa,CAAC,CAAQ,EAAA;QACpB,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;KAC1C;AAED;;;;;AAKG;AACH,IAAA,WAAW,CAAC,CAAQ,EAAA;AAClB,QAAA,MAAM,KAAK,GAAG,CAAC,CAAC,MAA0B,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC1C,QAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;KAC3B;AACD;;;;AAIG;AACH,IAAA,YAAY,CAAC,CAAQ,EAAA;AACnB,QAAA,MAAM,KAAK,GAAG,CAAC,CAAC,MAA0B,CAAC;AAC3C,QAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAC1B,QAAA,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;KAC3D;AAED,IAAA,IAAI,IAAI,GAAA;AACN,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;KAC7B;AAED,IAAA,IAAI,QAAQ,GAAA;AACV,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;KACjC;AAED,IAAA,IAAI,iBAAiB,GAAA;AACnB,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC;KAC1C;AAED,IAAA,IAAI,YAAY,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;KACrC;AACD;;AAEG;IACH,kBAAkB,GAAA;AAChB,QAAA,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;KAC3D;AACD;;AAEG;IACH,aAAa,GAAA;QACX,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;KACxC;AACD;;AAEG;IACH,aAAa,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;KACxC;AACD;;AAEG;IACH,cAAc,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;KACzC;AACD,IAAA,WAAW,CAAC,KAA0B,EAAE,OAAgB,EAAE,MAAoB,EAAA;AAC5E,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;KAC5D;AACD;;;AAGG;IACH,YAAY,GAAA;AACV,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAA6B,CAAC;AACxE,QAAA,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;KACrC;AACD;;AAEG;AACH,IAAA,aAAa,CAAC,KAAK,EAAA;;AAEjB,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;YAC1C,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;SACxC;;AAED,QAAA,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC;;AAElC,QAAA,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;;AAErB,YAAA,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE;;;AAG9B,gBAAA,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE;AACrB,oBAAA,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,QAAQ,EAAyB,CAAC;;;oBAG/D,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,GAAG,IAAI,EAAE,EAAE,KAAK,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;iBAC/F;aACF;SACF;aAAM;AACL,YAAA,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;SACjC;KACF;AACF;;;;"}
@@ -9,9 +9,12 @@ import { InputValidationController } from './inputValidationController.js';
9
9
  */
10
10
  const SgdsFormValidatorMixin = (superClass) => {
11
11
  class ToBeValidatedElement extends superClass {
12
- constructor() {
13
- super(...arguments);
12
+ // TypeScript requires mixin constructors to have rest parameter of type any[]
13
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
+ constructor(...args) {
15
+ super(...args);
14
16
  this._isTouched = false;
17
+ this._internals = this.attachInternals();
15
18
  }
16
19
  connectedCallback() {
17
20
  var _a;
@@ -29,9 +32,9 @@ const SgdsFormValidatorMixin = (superClass) => {
29
32
  (await this.sgdsInput) ||
30
33
  this.shadowRoot.querySelector("textarea") ||
31
34
  (await this.sgdsDatepickerInput);
35
+ this._mixinSetFormValue();
32
36
  if (this._mixinShouldSkipSgdsValidation())
33
37
  return;
34
- this._mixinSetFormValue();
35
38
  this._mixinValidate(this.input);
36
39
  }
37
40
  /**
@@ -58,6 +61,8 @@ const SgdsFormValidatorMixin = (superClass) => {
58
61
  */
59
62
  _mixinHandleChange(e) {
60
63
  this._mixinSetFormValue();
64
+ if (this._mixinShouldSkipSgdsValidation())
65
+ return;
61
66
  this.inputValidationController.handleChange(e);
62
67
  }
63
68
  /**
@@ -67,6 +72,8 @@ const SgdsFormValidatorMixin = (superClass) => {
67
72
  */
68
73
  _mixinHandleInputChange(e) {
69
74
  this._mixinSetFormValue();
75
+ if (this._mixinShouldSkipSgdsValidation())
76
+ return;
70
77
  this.inputValidationController.handleInput(e);
71
78
  }
72
79
  /**
@@ -78,30 +85,41 @@ const SgdsFormValidatorMixin = (superClass) => {
78
85
  * 4. Reset touched state to false for a pristine form
79
86
  */
80
87
  _mixinResetValidity(input) {
88
+ if (this._mixinShouldSkipSgdsValidation())
89
+ return;
81
90
  this.inputValidationController.resetValidity();
82
91
  this.inputValidationController.updateInvalidState();
83
92
  this.inputValidationController.validateInput(input);
84
93
  this._isTouched ? (this._isTouched = false) : null;
85
94
  }
86
95
  _mixinValidate(input) {
96
+ if (this._mixinShouldSkipSgdsValidation())
97
+ return;
87
98
  this.inputValidationController.validateInput(input);
88
99
  }
89
100
  _mixinSetFormValue() {
90
- this.inputValidationController.setFormValue();
101
+ const value = this.value;
102
+ this._internals.setFormValue(value);
91
103
  }
92
104
  _mixinCheckValidity() {
105
+ if (this._mixinShouldSkipSgdsValidation())
106
+ return true;
93
107
  return this.inputValidationController.checkValidity();
94
108
  }
95
109
  _mixinReportValidity() {
110
+ if (this._mixinShouldSkipSgdsValidation())
111
+ return true;
96
112
  return this.inputValidationController.reportValidity();
97
113
  }
98
114
  _mixinGetValidity() {
99
- return this.inputValidationController.validity;
115
+ return this._internals.validity;
100
116
  }
101
117
  _mixinGetValidationMessage() {
102
- return this.inputValidationController.validationMessage;
118
+ return this._internals.validationMessage;
103
119
  }
104
120
  _mixinSetValidity(flags, message, anchor) {
121
+ if (this._mixinShouldSkipSgdsValidation())
122
+ return;
105
123
  return this.inputValidationController.setValidity(flags, message, anchor);
106
124
  }
107
125
  // Only check for noValidate prop
@@ -1 +1 @@
1
- {"version":3,"file":"validatorMixin.js","sources":["../../src/utils/validatorMixin.ts"],"sourcesContent":["import { LitElement, PropertyValueMap } from \"lit\";\nimport { queryAsync } from \"lit/decorators.js\";\nimport { SgdsInput } from \"../components\";\nimport { InputValidationController } from \"./inputValidationController\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Constructor<T> = new (...args: any[]) => T;\n\n/**\n * @summary The FormValidationMixin used by the form components\n * @param superClass\n * @returns\n */\nexport const SgdsFormValidatorMixin = <T extends Constructor<LitElement>>(superClass: T) => {\n class ToBeValidatedElement extends superClass {\n static formAssociated = true;\n inputValidationController: InputValidationController;\n input: HTMLInputElement | SgdsInput | HTMLTextAreaElement;\n private _isTouched = false;\n @queryAsync(\"sgds-input\") sgdsInput: Promise<SgdsInput>;\n @queryAsync(\"sgds-datepicker-input\") sgdsDatepickerInput: Promise<SgdsInput>;\n\n connectedCallback(): void {\n super.connectedCallback();\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n /** Idempotency guarantee */\n this.inputValidationController ??= new InputValidationController(this);\n }\n async firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n\n /* Either input or sgds-input. For example, quantity-toggle uses sgds-input */\n this.input =\n this.shadowRoot.querySelector(\"input\") ||\n (await this.sgdsInput) ||\n this.shadowRoot.querySelector(\"textarea\") ||\n (await this.sgdsDatepickerInput);\n\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n this._mixinSetFormValue();\n\n this._mixinValidate(this.input);\n }\n\n /**\n * Native lifecycle of Form-Associated Custom Element Callbacks\n */\n formResetCallback() {\n if (this._mixinResetFormControl) {\n this._mixinResetFormControl();\n } else {\n this.value = this.defaultValue;\n this._mixinResetValidity(this.input);\n }\n this._mixinSetFormValue();\n }\n /**\n *\n * Methods use by classes using this mixin\n */\n\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run change handler\n */\n _mixinHandleChange(e: Event): void {\n this._mixinSetFormValue();\n this.inputValidationController.handleChange(e);\n }\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run input handler\n */\n _mixinHandleInputChange(e: Event): void {\n this._mixinSetFormValue();\n this.inputValidationController.handleInput(e);\n }\n /**\n * During form resetting,\n * 1. ValidityState is reset\n * 2. invalid reactive prop is updated after the reset\n * 3. Revalidates the ValidityState (but do not update invalid prop)\n * to prepare for the next validity check\n * 4. Reset touched state to false for a pristine form\n */\n _mixinResetValidity(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n this.inputValidationController.resetValidity();\n this.inputValidationController.updateInvalidState();\n this.inputValidationController.validateInput(input);\n this._isTouched ? (this._isTouched = false) : null;\n }\n\n _mixinValidate(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n this.inputValidationController.validateInput(input);\n }\n _mixinSetFormValue() {\n this.inputValidationController.setFormValue();\n }\n _mixinCheckValidity(): boolean {\n return this.inputValidationController.checkValidity();\n }\n _mixinReportValidity(): boolean {\n return this.inputValidationController.reportValidity();\n }\n _mixinGetValidity(): ValidityState {\n return this.inputValidationController.validity;\n }\n _mixinGetValidationMessage(): string {\n return this.inputValidationController.validationMessage;\n }\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void {\n return this.inputValidationController.setValidity(flags, message, anchor);\n }\n // Only check for noValidate prop\n _mixinShouldSkipSgdsValidation() {\n const form = this.closest(\"form\");\n\n return form?.noValidate || this.noValidate;\n }\n\n /** DECLARED INSTANCE METHODS AND PROPERTIES*/\n\n /**\n * Resets a form control to its initial state\n */\n declare _mixinResetFormControl: () => void;\n declare value: string;\n declare defaultValue: string;\n declare defaultChecked: boolean;\n declare noValidate: boolean;\n }\n\n return ToBeValidatedElement as Constructor<ToBeValidatedElementInterface> & T;\n};\n\nexport declare class ToBeValidatedElementInterface {\n inputValidationController: InputValidationController;\n input: HTMLInputElement;\n _mixinHandleChange(e: Event): void;\n _mixinHandleInputChange(e: Event): void;\n _mixinResetValidity(input: HTMLInputElement | SgdsInput): void;\n _mixinValidate(input: HTMLInputElement | SgdsInput): void;\n _mixinSetFormValue(): void;\n _mixinCheckValidity(): boolean;\n _mixinReportValidity(): boolean;\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void;\n _mixinGetValidity(): ValidityState;\n _mixinGetValidationMessage(): string;\n _mixinShouldSkipSgdsValidation(): boolean;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validatorMixin.js","sources":["../../src/utils/validatorMixin.ts"],"sourcesContent":["import { LitElement, PropertyValueMap } from \"lit\";\nimport { queryAsync } from \"lit/decorators.js\";\nimport { SgdsInput } from \"../components\";\nimport { InputValidationController } from \"./inputValidationController\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Constructor<T> = new (...args: any[]) => T;\n\n/**\n * @summary The FormValidationMixin used by the form components\n * @param superClass\n * @returns\n */\nexport const SgdsFormValidatorMixin = <T extends Constructor<LitElement>>(superClass: T) => {\n class ToBeValidatedElement extends superClass {\n static formAssociated = true;\n inputValidationController: InputValidationController;\n input: HTMLInputElement | SgdsInput | HTMLTextAreaElement;\n private _isTouched = false;\n private _internals: ElementInternals;\n @queryAsync(\"sgds-input\") sgdsInput: Promise<SgdsInput>;\n @queryAsync(\"sgds-datepicker-input\") sgdsDatepickerInput: Promise<SgdsInput>;\n\n // TypeScript requires mixin constructors to have rest parameter of type any[]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(...args: any[]) {\n super(...args);\n this._internals = this.attachInternals();\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n /** Idempotency guarantee */\n this.inputValidationController ??= new InputValidationController(this);\n }\n async firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n\n /* Either input or sgds-input. For example, quantity-toggle uses sgds-input */\n this.input =\n this.shadowRoot.querySelector(\"input\") ||\n (await this.sgdsInput) ||\n this.shadowRoot.querySelector(\"textarea\") ||\n (await this.sgdsDatepickerInput);\n\n this._mixinSetFormValue();\n\n if (this._mixinShouldSkipSgdsValidation()) return;\n\n this._mixinValidate(this.input);\n }\n\n /**\n * Native lifecycle of Form-Associated Custom Element Callbacks\n */\n formResetCallback() {\n if (this._mixinResetFormControl) {\n this._mixinResetFormControl();\n } else {\n this.value = this.defaultValue;\n this._mixinResetValidity(this.input);\n }\n this._mixinSetFormValue();\n }\n /**\n *\n * Methods use by classes using this mixin\n */\n\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run change handler\n */\n _mixinHandleChange(e: Event): void {\n this._mixinSetFormValue();\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.handleChange(e);\n }\n /**\n * OnChange of form component\n * 1. Make value of control accessible via FormData\n * 2. Run input handler\n */\n _mixinHandleInputChange(e: Event): void {\n this._mixinSetFormValue();\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.handleInput(e);\n }\n /**\n * During form resetting,\n * 1. ValidityState is reset\n * 2. invalid reactive prop is updated after the reset\n * 3. Revalidates the ValidityState (but do not update invalid prop)\n * to prepare for the next validity check\n * 4. Reset touched state to false for a pristine form\n */\n _mixinResetValidity(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.resetValidity();\n this.inputValidationController.updateInvalidState();\n this.inputValidationController.validateInput(input);\n this._isTouched ? (this._isTouched = false) : null;\n }\n\n _mixinValidate(input: HTMLInputElement | SgdsInput | HTMLTextAreaElement) {\n if (this._mixinShouldSkipSgdsValidation()) return;\n this.inputValidationController.validateInput(input);\n }\n _mixinSetFormValue() {\n const value = this.value as string | FormData | File;\n this._internals.setFormValue(value);\n }\n _mixinCheckValidity(): boolean {\n if (this._mixinShouldSkipSgdsValidation()) return true;\n return this.inputValidationController.checkValidity();\n }\n _mixinReportValidity(): boolean {\n if (this._mixinShouldSkipSgdsValidation()) return true;\n return this.inputValidationController.reportValidity();\n }\n _mixinGetValidity(): ValidityState {\n return this._internals.validity;\n }\n _mixinGetValidationMessage(): string {\n return this._internals.validationMessage;\n }\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void {\n if (this._mixinShouldSkipSgdsValidation()) return;\n return this.inputValidationController.setValidity(flags, message, anchor);\n }\n // Only check for noValidate prop\n _mixinShouldSkipSgdsValidation() {\n const form = this.closest(\"form\");\n\n return form?.noValidate || this.noValidate;\n }\n\n /** DECLARED INSTANCE METHODS AND PROPERTIES*/\n\n /**\n * Resets a form control to its initial state\n */\n declare _mixinResetFormControl: () => void;\n declare value: string;\n declare defaultValue: string;\n declare defaultChecked: boolean;\n declare noValidate: boolean;\n }\n\n return ToBeValidatedElement as Constructor<ToBeValidatedElementInterface> & T;\n};\n\nexport declare class ToBeValidatedElementInterface {\n inputValidationController: InputValidationController;\n input: HTMLInputElement;\n _mixinHandleChange(e: Event): void;\n _mixinHandleInputChange(e: Event): void;\n _mixinResetValidity(input: HTMLInputElement | SgdsInput): void;\n _mixinValidate(input: HTMLInputElement | SgdsInput): void;\n _mixinSetFormValue(): void;\n _mixinCheckValidity(): boolean;\n _mixinReportValidity(): boolean;\n _mixinSetValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void;\n _mixinGetValidity(): ValidityState;\n _mixinGetValidationMessage(): string;\n _mixinShouldSkipSgdsValidation(): boolean;\n}\n"],"names":[],"mappings":"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"}