fix(form-core): Implement conversion of name attribute value to string type
This commit is contained in:
parent
08a1cb1688
commit
57597bb9ba
6 changed files with 67 additions and 17 deletions
5
.changeset/olive-meals-explode.md
Normal file
5
.changeset/olive-meals-explode.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@lion/ui': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
[form-core] Updated behavior of name attribute in FormRegisteringMixin to convert values to string type
|
||||||
|
|
@ -34,7 +34,6 @@ const FormControlMixinImplementation = superclass =>
|
||||||
/** @type {any} */
|
/** @type {any} */
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
name: { type: String, reflect: true },
|
|
||||||
readOnly: { type: Boolean, attribute: 'readonly', reflect: true },
|
readOnly: { type: Boolean, attribute: 'readonly', reflect: true },
|
||||||
label: String, // FIXME: { attribute: false } breaks a bunch of tests, but shouldn't...
|
label: String, // FIXME: { attribute: false } breaks a bunch of tests, but shouldn't...
|
||||||
labelSrOnly: { type: Boolean, attribute: 'label-sr-only', reflect: true },
|
labelSrOnly: { type: Boolean, attribute: 'label-sr-only', reflect: true },
|
||||||
|
|
@ -156,14 +155,6 @@ const FormControlMixinImplementation = superclass =>
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
/**
|
|
||||||
* The name the element will be registered with to the .formElements collection
|
|
||||||
* of the parent. Also, it serves as the key of key/value pairs in
|
|
||||||
* modelValue/serializedValue objects
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
this.name = '';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Boolean attribute which, if present, indicates that the user should not be able to edit
|
* A Boolean attribute which, if present, indicates that the user should not be able to edit
|
||||||
* the value of the input. The difference between disabled and readonly is that read-only
|
* the value of the input. The difference between disabled and readonly is that read-only
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,14 @@ const FormRegisteringMixinImplementation = superclass =>
|
||||||
class extends superclass {
|
class extends superclass {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
/**
|
||||||
|
* The name the element will be registered with to the .formElements collection
|
||||||
|
* of the parent. Also, it serves as the key of key/value pairs in
|
||||||
|
* modelValue/serializedValue objects
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this.name = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The registrar this FormControl registers to, Usually a descendant of FormGroup or
|
* The registrar this FormControl registers to, Usually a descendant of FormGroup or
|
||||||
* ChoiceGroup
|
* ChoiceGroup
|
||||||
|
|
@ -37,8 +45,28 @@ const FormRegisteringMixinImplementation = superclass =>
|
||||||
this.allowCrossRootRegistration = false;
|
this.allowCrossRootRegistration = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name attribute for the control.
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
get name() {
|
||||||
|
return this.__name || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts values provided for the `name` attribute to string type.
|
||||||
|
* Mimics the native `input` behavior.
|
||||||
|
* @param {string} newName
|
||||||
|
*/
|
||||||
|
set name(newName) {
|
||||||
|
const oldName = this.name;
|
||||||
|
this.__name = newName.toString();
|
||||||
|
this.requestUpdate('name', oldName);
|
||||||
|
}
|
||||||
|
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
|
name: { type: String, reflect: true },
|
||||||
allowCrossRootRegistration: { type: Boolean, attribute: 'allow-cross-root-registration' },
|
allowCrossRootRegistration: { type: Boolean, attribute: 'allow-cross-root-registration' },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -310,6 +310,23 @@ export const runRegistrationSuite = customConfig => {
|
||||||
expect(eventSpy).to.have.been.calledOnce;
|
expect(eventSpy).to.have.been.calledOnce;
|
||||||
expect(eventSpy.getCall(0).args[0].composed).to.equal(false);
|
expect(eventSpy.getCall(0).args[0].composed).to.equal(false);
|
||||||
});
|
});
|
||||||
|
it('accepts a name attribute and converts the values provided to a string', async () => {
|
||||||
|
const elAttr = /** @type {RegisteringClass} */ (
|
||||||
|
await fixture(html`<${childTag} name=${5}></${childTag}>`)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(elAttr.hasAttribute('name')).to.be.true;
|
||||||
|
expect(elAttr.name).to.be.a('string');
|
||||||
|
expect(elAttr.name).to.equal('5', 'as an attribute');
|
||||||
|
|
||||||
|
const elProp = /** @type {RegisteringClass} */ (
|
||||||
|
await fixture(html`<${childTag} .name=${5}></${childTag}>`)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(elProp.hasAttribute('name')).to.be.true;
|
||||||
|
expect(elProp.name).to.be.a('string');
|
||||||
|
expect(elProp.name).to.equal('5', 'as a property');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('FormRegistrarPortalMixin', () => {
|
describe('FormRegistrarPortalMixin', () => {
|
||||||
it('forwards registrations to the .registrationTarget', async () => {
|
it('forwards registrations to the .registrationTarget', async () => {
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,6 @@ export declare interface HTMLElementWithValue extends HTMLElement {
|
||||||
export declare class FormControlHost {
|
export declare class FormControlHost {
|
||||||
static get styles(): CSSResultArray;
|
static get styles(): CSSResultArray;
|
||||||
static get properties(): {
|
static get properties(): {
|
||||||
name: {
|
|
||||||
type: StringConstructor;
|
|
||||||
reflect: boolean;
|
|
||||||
};
|
|
||||||
readOnly: {
|
readOnly: {
|
||||||
type: BooleanConstructor;
|
type: BooleanConstructor;
|
||||||
attribute: string;
|
attribute: string;
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,13 @@ import { LitElement } from 'lit';
|
||||||
import { FormRegistrarHost } from './FormRegistrarMixinTypes.js';
|
import { FormRegistrarHost } from './FormRegistrarMixinTypes.js';
|
||||||
|
|
||||||
export declare class FormRegisteringHost {
|
export declare class FormRegisteringHost {
|
||||||
/**
|
static get properties(): {
|
||||||
* The name the host is registered with to a parent
|
name: {
|
||||||
*/
|
type: StringConstructor;
|
||||||
name: string;
|
reflect: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To encourage accessibility best practices, `form-element-register` events
|
* To encourage accessibility best practices, `form-element-register` events
|
||||||
* do not pierce through shadow roots. This forces the developer to create form groups and fieldsets that
|
* do not pierce through shadow roots. This forces the developer to create form groups and fieldsets that
|
||||||
|
|
@ -17,12 +20,22 @@ export declare class FormRegisteringHost {
|
||||||
*/
|
*/
|
||||||
allowCrossRootRegistration: boolean;
|
allowCrossRootRegistration: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name the element will be registered with to the .formElements collection
|
||||||
|
* of the parent. Also, it serves as the key of key/value pairs in
|
||||||
|
* modelValue/serializedValue objects
|
||||||
|
*/
|
||||||
|
get name(): string;
|
||||||
|
set name(arg: any);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The registrar this FormControl registers to, Usually a descendant of FormGroup or
|
* The registrar this FormControl registers to, Usually a descendant of FormGroup or
|
||||||
* ChoiceGroup
|
* ChoiceGroup
|
||||||
*/
|
*/
|
||||||
protected _parentFormGroup: FormRegistrarHost | undefined;
|
protected _parentFormGroup: FormRegistrarHost | undefined;
|
||||||
|
|
||||||
|
private __name: string;
|
||||||
|
|
||||||
private __unregisterFormElement: void;
|
private __unregisterFormElement: void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue