This commit is contained in:
konnorrogers
2024-05-10 21:43:41 -04:00
parent 4342242455
commit 797d6d1eb1
15 changed files with 61 additions and 77 deletions

View File

@@ -302,5 +302,5 @@ describe('<wa-button>', async () => {
control.href = 'some-url';
}
})
])
]);
});

View File

@@ -12,7 +12,6 @@ import { WebAwesomeFormAssociated } from '../../internal/webawesome-element.js';
import componentStyles from '../../styles/component.styles.js';
import styles from './checkbox.styles.js';
import type { CSSResultGroup, PropertyValues } from 'lit';
import { CustomErrorValidator } from '../../internal/validators/custom-error-validator.js';
/**
* @summary Checkboxes allow the user to toggle an option on or off.
@@ -57,7 +56,11 @@ export default class WaCheckbox extends WebAwesomeFormAssociated {
return [
...super.validators,
GroupRequiredValidator({
validationElement: Object.assign(document.createElement("input"), { type: "checkbox", required: true, name: "__validationCheckbox__" })
validationElement: Object.assign(document.createElement('input'), {
type: 'checkbox',
required: true,
name: '__validationCheckbox__'
})
})
];
}
@@ -132,7 +135,7 @@ export default class WaCheckbox extends WebAwesomeFormAssociated {
handleDefaultCheckedChange() {
if (!this.hasInteracted && this.checked !== this.defaultChecked) {
this.checked = this.defaultChecked;
this.handleValueOrCheckedChange()
this.handleValueOrCheckedChange();
}
}
@@ -153,19 +156,18 @@ export default class WaCheckbox extends WebAwesomeFormAssociated {
}
protected willUpdate(changedProperties: PropertyValues<this>): void {
super.willUpdate(changedProperties)
super.willUpdate(changedProperties);
if (changedProperties.has("value") || changedProperties.has("checked")) {
this.handleValueOrCheckedChange()
if (changedProperties.has('value') || changedProperties.has('checked')) {
this.handleValueOrCheckedChange();
}
}
formResetCallback() {
// Evaluate checked before the super call because of our watcher on value.
super.formResetCallback();
this.checked = this.defaultChecked;
this.handleValueOrCheckedChange()
this.handleValueOrCheckedChange();
}
/** Simulates a click on the checkbox. */

View File

@@ -95,13 +95,10 @@ declare const EyeDropper: EyeDropperConstructor;
export default class WaColorPicker extends WebAwesomeFormAssociated {
static styles: CSSResultGroup = [componentStyles, styles];
static shadowRootOptions = {...LitElement.shadowRootOptions, delegatesFocus: true }
static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };
static get validators() {
return [
...super.validators,
RequiredValidator()
];
return [...super.validators, RequiredValidator()];
}
private isSafeValue = false;

View File

@@ -1,9 +1,9 @@
// eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
import { aTimeout, elementUpdated, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import { serialize } from '../../../dist/webawesome.js';
import { isSafari } from '../../internal/test.js';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests.js'; // must come from the same module
import { sendKeys } from '@web/test-runner-commands';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests.js';
import { sendKeys } from '@web/test-runner-commands'; // must come from the same module
import { serialize } from '../../../dist/webawesome.js';
import sinon from 'sinon';
import type WaInput from './input.js';
@@ -569,6 +569,4 @@ describe('<wa-input>', async () => {
});
await runFormControlBaseTests('wa-input');
});

View File

@@ -2,7 +2,7 @@ import '../icon/icon.js';
import { classMap } from 'lit/directives/class-map.js';
import { customElement, property, query, state } from 'lit/decorators.js';
import { HasSlotController } from '../../internal/slot.js';
import { LitElement, html } from 'lit';
import { html, LitElement } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import { live } from 'lit/directives/live.js';
import { LocalizeController } from '../../utilities/localize.js';
@@ -59,13 +59,10 @@ import type { CSSResultGroup } from 'lit';
export default class WaInput extends WebAwesomeFormAssociated {
static styles: CSSResultGroup = [componentStyles, formControlStyles, styles];
static shadowRootOptions = {...LitElement.shadowRootOptions, delegatesFocus: true }
static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };
static get validators() {
return [
...super.validators,
MirrorValidator()
];
return [...super.validators, MirrorValidator()];
}
assumeInteractionOn = ['wa-blur', 'wa-input'];

View File

@@ -46,7 +46,11 @@ export default class WaRadioGroup extends WebAwesomeFormAssociated {
return [
...super.validators,
RequiredValidator({
validationElement: Object.assign(document.createElement("input"), { required: true, type: "radio", name: "__validationRadio__" })
validationElement: Object.assign(document.createElement('input'), {
required: true,
type: 'radio',
name: '__validationRadio__'
})
})
];
}

View File

@@ -48,10 +48,7 @@ export default class WaRange extends WebAwesomeFormAssociated {
static styles: CSSResultGroup = [componentStyles, formControlStyles, styles];
static get validators() {
return [
...super.validators,
MirrorValidator()
];
return [...super.validators, MirrorValidator()];
}
private readonly hasSlotController = new HasSlotController(this, 'help-text', 'label');

View File

@@ -82,7 +82,7 @@ export default class WaSelect extends WebAwesomeFormAssociated {
return [
...super.validators,
RequiredValidator({
validationElement: Object.assign(document.createElement("select"), {required: true})
validationElement: Object.assign(document.createElement('select'), { required: true })
})
];
}

View File

@@ -52,11 +52,8 @@ import type { CSSResultGroup, PropertyValues } from 'lit';
export default class WaSwitch extends WebAwesomeFormAssociated {
static styles: CSSResultGroup = [componentStyles, formControlStyles, styles];
static get validators () {
return [
...super.validators,
MirrorValidator()
]
static get validators() {
return [...super.validators, MirrorValidator()];
}
private readonly hasSlotController = new HasSlotController(this, 'help-text');
@@ -97,10 +94,10 @@ export default class WaSwitch extends WebAwesomeFormAssociated {
/** The switch's help text. If you need to display HTML, use the `help-text` slot instead. */
@property({ attribute: 'help-text' }) helpText = '';
firstUpdated (changedProperties: PropertyValues<typeof this>) {
super.firstUpdated(changedProperties)
firstUpdated(changedProperties: PropertyValues<typeof this>) {
super.firstUpdated(changedProperties);
this.handleValueOrCheckedChange()
this.handleValueOrCheckedChange();
}
private handleBlur() {
@@ -141,7 +138,7 @@ export default class WaSwitch extends WebAwesomeFormAssociated {
@watch(['value', 'checked'], { waitUntilFirstUpdate: true })
handleValueOrCheckedChange() {
this.value = this.checked ? this.value || 'on' : null;
this.requestUpdate("value")
this.requestUpdate('value');
this.input.checked = this.checked; // force a sync update
// These @watch() commands seem to override the base element checks for changes, so we need to setValue for the form and and updateValidity()
this.setValue(this.value, this.value);
@@ -171,22 +168,22 @@ export default class WaSwitch extends WebAwesomeFormAssociated {
setValue(value: string | File | FormData | null, stateValue?: string | File | FormData | null | undefined): void {
if (!this.checked) {
this.value = null
this.internals.setFormValue(null, null)
return
this.value = null;
this.internals.setFormValue(null, null);
return;
}
if (!value) {
value = "on"
value = 'on';
}
this.internals.setFormValue(value, stateValue)
this.internals.setFormValue(value, stateValue);
}
formResetCallback(): void {
this.checked = this.defaultChecked
this.handleValueOrCheckedChange()
super.formResetCallback()
this.checked = this.defaultChecked;
this.handleValueOrCheckedChange();
super.formResetCallback();
}
render() {

View File

@@ -45,10 +45,7 @@ import type { CSSResultGroup } from 'lit';
export default class WaTextarea extends WebAwesomeFormAssociated {
static styles: CSSResultGroup = [componentStyles, formControlStyles, styles];
static get validators() {
return [
...super.validators,
MirrorValidator()
];
return [...super.validators, MirrorValidator()];
}
assumeInteractionOn = ['wa-blur', 'wa-input'];

View File

@@ -1,6 +1,5 @@
import { expect, fixture } from '@open-wc/testing';
import type { WebAwesomeFormControl } from '../webawesome-element.js';
import WaButton from '../../components/button/button.js';
type CreateControlFn = () => Promise<WebAwesomeFormControl>;
@@ -52,7 +51,7 @@ async function runAllValidityTests(
displayName: string,
createControl: () => Promise<WebAwesomeFormControl>
) {
await new Promise<void>((resolve) => {
await new Promise<void>(resolve => {
// will be used later to retrieve meta information about the control
describe(`Form validity base test for ${displayName}`, async () => {
it('should have a property `validity` of type `object`', async () => {
@@ -170,7 +169,6 @@ async function runAllValidityTests(
// expect(control.hasInteracted).to.equal(false)
// });
// it('Should be invalid if a `customError` property is passed.', async () => {
// const control = await createControl();
// expect(control.validity.valid).to.equal(true)
@@ -179,7 +177,6 @@ async function runAllValidityTests(
// expect(control.validity.valid).to.equal(false)
// expect(control.validationMessage).to.equal("MyError")
// });
}
// Run special tests depending on component type
@@ -195,9 +192,8 @@ async function runAllValidityTests(
}
});
resolve()
})
resolve();
});
}
//

View File

@@ -6,7 +6,7 @@ import type { Validator } from '../webawesome-element.js';
*/
export const CustomErrorValidator = (): Validator => {
return {
observedAttributes: ["custom-error"],
observedAttributes: ['custom-error'],
checkValidity(element) {
const validity: ReturnType<Validator['checkValidity']> = {
message: '',
@@ -15,12 +15,12 @@ export const CustomErrorValidator = (): Validator => {
};
if (element.customError) {
validity.message = element.customError
validity.isValid = false
validity.invalidKeys = ["customError"]
validity.message = element.customError;
validity.isValid = false;
validity.invalidKeys = ['customError'];
}
return validity
return validity;
}
};
};

View File

@@ -1,6 +1,5 @@
import type { Validator } from '../webawesome-element.js';
export interface GroupRequiredValidatorOptions {
/** This is a cheap way for us to get translation strings for the user without having proper translations. */
validationElement: HTMLInputElement;
@@ -9,7 +8,7 @@ export interface GroupRequiredValidatorOptions {
// Used to validate groups of elements and not just a single element.
// https://codepen.io/paramagicdev/pen/eYorwrz
export const GroupRequiredValidator = (options: GroupRequiredValidatorOptions): Validator => {
const { validationElement } = options
const { validationElement } = options;
const obj: Validator = {
observedAttributes: ['required'],

View File

@@ -6,10 +6,10 @@ export interface RequiredValidatorOptions {
}
export const RequiredValidator = (options: RequiredValidatorOptions = {}): Validator => {
let { validationElement } = options
let { validationElement } = options;
if (!validationElement) {
validationElement = Object.assign(document.createElement("input"), { required: true })
validationElement = Object.assign(document.createElement('input'), { required: true });
}
const obj: Validator = {

View File

@@ -156,9 +156,7 @@ export class WebAwesomeFormAssociated
* for changes. Whenever these attributes change, we want to be notified and update the validator.
*/
static get validators(): Validator[] {
return [
CustomErrorValidator()
];
return [CustomErrorValidator()];
}
// Append all Validator "observedAttributes" into the "observedAttributes" so they can run.
@@ -201,7 +199,7 @@ export class WebAwesomeFormAssociated
@property({ state: true }) hasInteracted: boolean = false;
// This works around a limitation in Safari. It is a hacky way for us to preserve customErrors generated by the user.
@property({ attribute: "custom-error", reflect: true }) customError: string | null = null
@property({ attribute: 'custom-error', reflect: true }) customError: string | null = null;
private emittedEvents: string[] = [];
@@ -245,15 +243,17 @@ export class WebAwesomeFormAssociated
if (e.target !== this) return;
// An "invalid" event counts as interacted, this is usually triggered by a button "submitting"
this.hasInteracted = true
this.hasInteracted = true;
this.emit('wa-invalid');
};
protected willUpdate(changedProperties: PropertyValues<this>) {
if (changedProperties.has("customError")) {
if (changedProperties.has('customError')) {
// We use null because it we really don't want it to show up in the attributes because `custom-error` does reflect.
if (!this.customError) { this.customError = null }
this.setCustomValidity(this.customError || "")
if (!this.customError) {
this.customError = null;
}
this.setCustomValidity(this.customError || '');
}
if (changedProperties.has('defaultValue')) {
@@ -338,7 +338,7 @@ export class WebAwesomeFormAssociated
reportValidity() {
this.updateValidity();
// This seems reasonable. `reportValidity()` is kind of like "we expect you to have interacted"
this.hasInteracted = true
this.hasInteracted = true;
return this.internals.reportValidity();
}