Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Automatic attribute updates for form-associated proxy #4169

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 5 additions & 1 deletion packages/web-components/fast-element/src/attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export class AttributeDefinition implements Accessor {
* @param source - The source element to access.
* @param value - The value to set the attribute/property to.
*/
public setValue(source: HTMLElement, newValue: any): void {
public setValue(source: any, newValue: any): void {
const oldValue = source[this.fieldName];
const converter = this.converter;

Expand All @@ -192,6 +192,10 @@ export class AttributeDefinition implements Accessor {
source[this.callbackName](oldValue, newValue);
}

if (source.updateProxy) {
source.updateProxy(this.name, newValue);
}

((source as any).$fastController as Notifier).notify(this.name);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ class DefaultObservableAccessor implements Accessor {
callback.call(source, oldValue, newValue);
}

if (source.updateProxy) {
source.updateProxy(this.name, newValue);
}

/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
getNotifier(source).notify(this.name);
}
Expand Down
29 changes: 0 additions & 29 deletions packages/web-components/fast-foundation/src/button/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ export class Button extends FormAssociatedButton {
*/
@attr
public formaction: string;
private formactionChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.formAction = this.formaction;
}
}

/**
* See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button | <button> element} for more details.
Expand All @@ -54,11 +49,6 @@ export class Button extends FormAssociatedButton {
*/
@attr
public formenctype: string;
private formenctypeChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.formEnctype = this.formenctype;
}
}

/**
* See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button | <button> element} for more details.
Expand All @@ -69,11 +59,6 @@ export class Button extends FormAssociatedButton {
*/
@attr
public formmethod: string;
private formmethodChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.formMethod = this.formmethod;
}
}

/**
* See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button | <button> element} for more details.
Expand All @@ -84,11 +69,6 @@ export class Button extends FormAssociatedButton {
*/
@attr({ mode: "boolean" })
public formnovalidate: boolean;
private formnovalidateChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.formNoValidate = this.formnovalidate;
}
}

/**
* See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button | <button> element} for more details.
Expand All @@ -99,11 +79,6 @@ export class Button extends FormAssociatedButton {
*/
@attr
public formtarget: "_self" | "_blank" | "_parent" | "_top";
private formtargetChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.formTarget = this.formtarget;
}
}

/**
* The button type.
Expand All @@ -118,10 +93,6 @@ export class Button extends FormAssociatedButton {
previous: "submit" | "reset" | "button" | void,
next: "submit" | "reset" | "button"
): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.type = this.type;
}

next === "submit" && this.addEventListener("click", this.handleSubmission);
previous === "submit" && this.removeEventListener("click", this.handleSubmission);
next === "reset" && this.addEventListener("click", this.handleFormReset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ export class Checkbox extends FormAssociatedCheckbox {
*/
@attr({ attribute: "readonly", mode: "boolean" })
public readOnly: boolean; // Map to proxy element
private readOnlyChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.readOnly = this.readOnly;
}
}

/**
* The element's value to be included in form submission when checked.
Expand Down Expand Up @@ -81,16 +76,11 @@ export class Checkbox extends FormAssociatedCheckbox {
this.dirtyChecked = true;
}

this.updateForm();

if (this.proxy instanceof HTMLElement) {
this.proxy.checked = this.checked;
}

if (this.constructed) {
this.$emit("change");
}

this.updateForm();
this.validate();
}

Expand Down Expand Up @@ -124,7 +114,7 @@ export class Checkbox extends FormAssociatedCheckbox {
public connectedCallback(): void {
super.connectedCallback();

this.proxy.setAttribute("type", "checkbox");
this.updateProxy("type", "checkbox");

this.updateForm();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,6 @@ export function FormAssociated<T extends ConstructableFormAssociated>(BaseCtor:
public valueChanged(previous: string, next: string) {
this.dirtyValue = true;

if (this.proxy instanceof HTMLElement) {
this.proxy.value = this.value;
}

this.setFormValue(this.value);
this.validate();
}
Expand Down Expand Up @@ -347,10 +343,6 @@ export function FormAssociated<T extends ConstructableFormAssociated>(BaseCtor:
* proper functioning of `FormAssociated`
*/
public disabledChanged(previous: boolean, next: boolean): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.disabled = this.disabled;
}

DOM.queueUpdate(() => this.classList.toggle("disabled", this.disabled));
}

Expand All @@ -362,23 +354,6 @@ export function FormAssociated<T extends ConstructableFormAssociated>(BaseCtor:
*/
public name: string;

/**
* Invoked when the `name` property changes
*
* @param previous - the previous value
* @param next - the new value
*
* @remarks
* If elements extending `FormAssociated` implement a `nameChanged` method
* They must be sure to invoke `super.nameChanged(previous, next)` to ensure
* proper functioning of `FormAssociated`
*/
public nameChanged(previous, next): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.name = this.name;
}
}

/**
* Require the field to be completed prior to form submission.
*
Expand All @@ -399,10 +374,6 @@ export function FormAssociated<T extends ConstructableFormAssociated>(BaseCtor:
* proper functioning of `FormAssociated`
*/
public requiredChanged(prev: boolean, next: boolean): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.required = this.required;
}

DOM.queueUpdate(() => this.classList.toggle("required", this.required));
this.validate();
}
Expand Down Expand Up @@ -568,6 +539,21 @@ export function FormAssociated<T extends ConstructableFormAssociated>(BaseCtor:
this.appendChild(this.proxy);
}

/**
* Updates attributes on the proxy element
* @param name - The name of the attribute to be updated
* @param value - The value of the attribute
*/
public updateProxy(name: string, value: any): void {
if (this.proxy instanceof HTMLElement) {
if (value === null || value === false) {
this.proxy.removeAttribute(name);
} else {
this.proxy.setAttribute(name, `${value}`);
}
}
}

/**
* Detach the proxy element from the DOM
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ export class ListboxOption extends FASTElement {
protected defaultSelectedChanged(): void {
if (!this.dirtySelected) {
this.selected = this.defaultSelected;

if (this.proxy instanceof HTMLOptionElement) {
this.proxy.selected = this.defaultSelected;
}
}
}

Expand All @@ -41,11 +37,6 @@ export class ListboxOption extends FASTElement {
*/
@attr({ mode: "boolean" })
public disabled: boolean;
protected disabledChanged(prev, next): void {
if (this.proxy instanceof HTMLOptionElement) {
this.proxy.disabled = this.disabled;
}
}

/**
* The selected attribute value. This sets the initial selected value.
Expand All @@ -58,10 +49,6 @@ export class ListboxOption extends FASTElement {
public selectedAttribute: boolean;
protected selectedAttributeChanged(): void {
this.defaultSelected = this.selectedAttribute;

if (this.proxy instanceof HTMLOptionElement) {
this.proxy.defaultSelected = this.defaultSelected;
}
}

/**
Expand All @@ -77,10 +64,6 @@ export class ListboxOption extends FASTElement {
this.dirtySelected = true;
}

if (this.proxy instanceof HTMLOptionElement) {
this.proxy.selected = this.selected;
}

this.$emit("change");
}
}
Expand Down Expand Up @@ -120,16 +103,18 @@ export class ListboxOption extends FASTElement {
public value: string;
public valueChanged(previous: string, next: string) {
this.dirtyValue = true;

if (this.proxy instanceof HTMLElement) {
this.proxy.value = this.value;
}
}

public get form(): HTMLFormElement | null {
return this.proxy ? this.proxy.form : null;
}

public updateProxy(name: string, value: any): void {
if (this.proxy instanceof HTMLOptionElement) {
this.proxy[name] = value;
}
}

public constructor(
text?: string,
value?: string,
Expand Down
9 changes: 0 additions & 9 deletions packages/web-components/fast-foundation/src/radio/radio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ export class Radio extends FormAssociatedRadio implements RadioControl {
*/
@attr({ attribute: "readonly", mode: "boolean" })
public readOnly: boolean; // Map to proxy element
private readOnlyChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.readOnly = this.readOnly;
}
}

/**
* The name of the radio. See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname | name attribute} for more info.
Expand Down Expand Up @@ -102,10 +97,6 @@ export class Radio extends FormAssociatedRadio implements RadioControl {

this.updateForm();

if (this.proxy instanceof HTMLElement) {
this.proxy.checked = this.checked;
}

this.$emit("change");

this.validate();
Expand Down
20 changes: 2 additions & 18 deletions packages/web-components/fast-foundation/src/slider/slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,7 @@ export class Slider extends FormAssociatedSlider implements SliderConfiguration
* HTML Attribute: readonly
*/
@attr({ attribute: "readonly", mode: "boolean" })
public readOnly: boolean; // Map to proxy element
private readOnlyChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.readOnly = this.readOnly;
}
}
public readOnly: boolean;

/**
* @internal
Expand Down Expand Up @@ -145,11 +140,7 @@ export class Slider extends FormAssociatedSlider implements SliderConfiguration
@attr({ converter: nullableNumberConverter })
public min: number = 0; // Map to proxy element.
private minChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.min = `${this.min}`;
}

this.validate;
this.validate();
}

/**
Expand All @@ -163,9 +154,6 @@ export class Slider extends FormAssociatedSlider implements SliderConfiguration
@attr({ converter: nullableNumberConverter })
public max: number = 10; // Map to proxy element.
private maxChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.max = `${this.max}`;
}
this.validate();
}

Expand All @@ -179,10 +167,6 @@ export class Slider extends FormAssociatedSlider implements SliderConfiguration
@attr({ converter: nullableNumberConverter })
public step: number = 1; // Map to proxy element.
private stepChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.step = `${this.step}`;
}

this.validate();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ export class Switch extends FormAssociatedSwitch {
@attr({ attribute: "readonly", mode: "boolean" })
public readOnly: boolean; // Map to proxy element
private readOnlyChanged(): void {
if (this.proxy instanceof HTMLElement) {
this.proxy.readOnly = this.readOnly;
}

this.readOnly
? this.classList.add("readonly")
: this.classList.remove("readonly");
Expand Down Expand Up @@ -85,10 +81,6 @@ export class Switch extends FormAssociatedSwitch {

this.updateForm();

if (this.proxy instanceof HTMLElement) {
this.proxy.checked = this.checked;
}

this.$emit("change");

this.checked ? this.classList.add("checked") : this.classList.remove("checked");
Expand Down
Loading