Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions packages/base/src/UI5Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,7 @@ abstract class UI5Element extends HTMLElement {
await this._processChildren();
}

if (!ctor.asyncFinished) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not the same - if the asyncFinished is true, the promise is not awaited and the whole method remains sync. if you await (even a finished promise), the method becomes async

await ctor.definePromise;
}
await this.definePromiseSafe;

if (!this._inDOM) { // Component removed from DOM while _processChildren was running
return;
Expand All @@ -340,6 +338,14 @@ abstract class UI5Element extends HTMLElement {
this.onEnterDOM();
}

get definePromiseSafe() {
const ctor = this.constructor as typeof UI5Element;
if (!ctor.asyncFinished && ctor.definePromise) {
return ctor.definePromise;
}
return Promise.resolve();
}

/**
* Do not call this method from derivatives of UI5Element, use "onExitDOM" only
* @private
Expand Down
30 changes: 22 additions & 8 deletions packages/base/src/features/InputElementsFormSupport.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import type UI5Element from "../UI5Element.js";

type FormattedValue = FormData | string | null;
type ElementAnchor = HTMLElement | undefined;

interface IFormInputElement extends UI5Element {
name?: string;
formFormattedValue: FormData | string | null;
formValidityMessage?: string;
formValidity?: ValidityStateFlags;
formElementAnchor?: () => HTMLElement | undefined | Promise<HTMLElement | undefined>;
formFormattedValue: FormattedValue | Promise<FormattedValue>;
formValidityMessage?: string | Promise<string>;
formValidity?: ValidityStateFlags | Promise<ValidityStateFlags>;
formElementAnchor?: () => ElementAnchor | Promise<ElementAnchor>;
}

const updateFormValue = (element: IFormInputElement | UI5Element) => {
Expand All @@ -14,7 +17,7 @@ const updateFormValue = (element: IFormInputElement | UI5Element) => {
}
};

const setFormValue = (element: IFormInputElement) => {
const setFormValue = async (element: IFormInputElement) => {
if (!element._internals?.form) {
return;
}
Expand All @@ -26,16 +29,27 @@ const setFormValue = (element: IFormInputElement) => {
return;
}

element._internals.setFormValue(element.formFormattedValue);
const formattedValue = element.formFormattedValue instanceof Promise
? await element.formFormattedValue
: element.formFormattedValue;
element._internals.setFormValue(formattedValue);
};

const setFormValidity = async (element: IFormInputElement) => {
if (!element._internals?.form) {
return;
}
if (element.formValidity && Object.keys(element.formValidity).some(key => key)) {
const formValidity = element.formValidity instanceof Promise
? await element.formValidity
: element.formValidity;

const formValidityMessage = element.formValidityMessage instanceof Promise
? await element.formValidityMessage
: element.formValidityMessage;

if (formValidity && Object.keys(formValidity).some(key => key)) {
const focusRef = await element.formElementAnchor?.();
element._internals.setValidity(element.formValidity, element.formValidityMessage, focusRef);
element._internals.setValidity(formValidity, formValidityMessage, focusRef);
} else {
element._internals.setValidity({});
}
Expand Down
38 changes: 20 additions & 18 deletions packages/main/src/StepInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,27 +301,29 @@ class StepInput extends UI5Element implements IFormInputElement {
}

get formValidityMessage() {
const validity = this.formValidity;

if (validity.patternMismatch) {
return StepInput.i18nBundle.getText(STEPINPUT_PATTER_MISSMATCH, this.valuePrecision);
}
if (validity.rangeUnderflow) {
return StepInput.i18nBundle.getText(STEPINPUT_RANGEUNDERFLOW, this.min as number);
}
if (validity.rangeOverflow) {
return StepInput.i18nBundle.getText(STEPINPUT_RANGEOVERFLOW, this.max as number);
}
return this.formValidity.then(validity => {
if (validity.patternMismatch) {
return StepInput.i18nBundle.getText(STEPINPUT_PATTER_MISSMATCH, this.valuePrecision);
}
if (validity.rangeUnderflow) {
return StepInput.i18nBundle.getText(STEPINPUT_RANGEUNDERFLOW, this.min as number);
}
if (validity.rangeOverflow) {
return StepInput.i18nBundle.getText(STEPINPUT_RANGEOVERFLOW, this.max as number);
}

return ""; // No error
return ""; // No error
});
}

get formValidity(): ValidityStateFlags {
return {
patternMismatch: this.value !== 0 && !this._isValueWithCorrectPrecision,
rangeOverflow: this.max !== undefined && this.value >= this.max,
rangeUnderflow: this.min !== undefined && this.value <= this.min,
};
get formValidity(): Promise<ValidityStateFlags> {
return this.definePromiseSafe.then(() => {
return {
patternMismatch: this.value !== 0 && !this._isValueWithCorrectPrecision,
rangeOverflow: this.max !== undefined && this.value >= this.max,
rangeUnderflow: this.min !== undefined && this.value <= this.min,
};
});
}

get formFormattedValue(): FormData | string | null {
Expand Down
Loading