simplify validation logic

pull/1120/head^2
Cory LaViska 2023-01-10 15:05:07 -05:00
rodzic 1fbb809057
commit 62c58b3a8c
1 zmienionych plików z 28 dodań i 47 usunięć

Wyświetl plik

@ -38,17 +38,16 @@ import type { CSSResultGroup } from 'lit';
export default class SlRadioGroup extends ShoelaceElement implements ShoelaceFormControl {
static styles: CSSResultGroup = styles;
protected readonly formControlController = new FormControlController(this, {
defaultValue: control => control.defaultValue
});
protected readonly formControlController = new FormControlController(this);
private readonly hasSlotController = new HasSlotController(this, 'help-text', 'label');
private customValidityMessage = '';
private validationTimeout: number;
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
@query('.radio-group__validation-input') input: HTMLInputElement;
@query('.radio-group__validation-input') validationInput: HTMLInputElement;
@state() private hasButtonGroup = false;
@state() private errorMessage = '';
@state() private customErrorMessage = '';
@state() defaultValue = '';
/**
@ -181,16 +180,10 @@ export default class SlRadioGroup extends ShoelaceElement implements ShoelaceFor
}
}
private showNativeErrorMessage() {
this.input.hidden = false;
this.input.reportValidity();
setTimeout(() => (this.input.hidden = true), 10000);
}
private updateCheckedRadio() {
const radios = this.getAllRadios();
radios.forEach(radio => (radio.checked = radio.value === this.value));
this.formControlController.setValidity(this.validity.valid);
this.formControlController.setValidity(this.checkValidity());
}
@watch('value')
@ -202,53 +195,41 @@ export default class SlRadioGroup extends ShoelaceElement implements ShoelaceFor
/** Checks for validity but does not show the browser's validation message. */
checkValidity() {
return this.validity.valid;
}
const isRequiredAndEmpty = this.required && !this.value;
const hasCustomValidityMessage = this.customValidityMessage !== '';
/** Sets a custom validation message. If `message` is not empty, the field will be considered invalid. */
setCustomValidity(message = '') {
this.customErrorMessage = message;
this.errorMessage = message;
if (!message) {
this.formControlController.setValidity(true);
} else {
this.formControlController.setValidity(false);
this.input.setCustomValidity(message);
if (isRequiredAndEmpty || hasCustomValidityMessage) {
return false;
}
return true;
}
get validity(): ValidityState {
const hasMissingData = !((this.value && this.required) || !this.required);
const hasCustomError = this.customErrorMessage !== '';
return {
badInput: false,
customError: hasCustomError,
patternMismatch: false,
rangeOverflow: false,
rangeUnderflow: false,
stepMismatch: false,
tooLong: false,
tooShort: false,
typeMismatch: false,
valid: hasMissingData || hasCustomError ? false : true,
valueMissing: !hasMissingData
};
/** Sets a custom validation message. Pass an empty string to restore validity. */
setCustomValidity(message = '') {
this.customValidityMessage = message;
this.errorMessage = message;
this.validationInput.setCustomValidity(message);
this.formControlController.updateValidity();
}
/** Checks for validity and shows the browser's validation message if the control is invalid. */
reportValidity(): boolean {
const validity = this.validity;
const isValid = this.checkValidity();
this.errorMessage = this.customErrorMessage || validity.valid ? '' : this.input.validationMessage;
this.formControlController.setValidity(validity.valid);
this.errorMessage = this.customValidityMessage || isValid ? '' : this.validationInput.validationMessage;
this.formControlController.setValidity(isValid);
this.validationInput.hidden = true;
clearTimeout(this.validationTimeout);
if (!validity.valid) {
this.showNativeErrorMessage();
if (!isValid) {
// Show the browser's constraint validation message
this.validationInput.hidden = false;
this.validationInput.reportValidity();
this.validationTimeout = setTimeout(() => (this.validationInput.hidden = true), 10000) as unknown as number;
}
return validity.valid;
return isValid;
}
render() {