kopia lustrzana https://github.com/shoelace-style/shoelace
Merge branch 'next' of https://github.com/shoelace-style/shoelace into konnorrogers/fix-dynamic-form-controls
commit
022bd0de0c
|
@ -16,6 +16,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti
|
||||||
|
|
||||||
- Added the ability to call `form.checkValidity()` and it will use Shoelace's custom `checkValidity()` handler. [#1708]
|
- Added the ability to call `form.checkValidity()` and it will use Shoelace's custom `checkValidity()` handler. [#1708]
|
||||||
- Fixed a bug with form controls removing the custom validity handlers from the form. [#1708]
|
- Fixed a bug with form controls removing the custom validity handlers from the form. [#1708]
|
||||||
|
- Fixed a bug in form control components that used a `form` property, but not an attribute. [#1707]
|
||||||
- Fixed a bug with bundled components using CDN builds not having translations on initial connect [#1696]
|
- Fixed a bug with bundled components using CDN builds not having translations on initial connect [#1696]
|
||||||
- Fixed a bug where the `"sl-change"` event would always fire simultaneously with `"sl-input"` event in `<sl-color-picker>`. The `<sl-change>` event now only fires when a user stops dragging a slider or stops dragging on the color canvas. [#1689]
|
- Fixed a bug where the `"sl-change"` event would always fire simultaneously with `"sl-input"` event in `<sl-color-picker>`. The `<sl-change>` event now only fires when a user stops dragging a slider or stops dragging on the color canvas. [#1689]
|
||||||
- Updated the copy icon in the system library [#1702]
|
- Updated the copy icon in the system library [#1702]
|
||||||
|
|
|
@ -45,20 +45,9 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly formControlController = new FormControlController(this, {
|
private readonly formControlController = new FormControlController(this, {
|
||||||
form: input => {
|
|
||||||
// Buttons support a form attribute that points to an arbitrary form, so if this attribute is set we need to query
|
|
||||||
// the form from the same root using its id
|
|
||||||
if (input.hasAttribute('form')) {
|
|
||||||
const doc = input.getRootNode() as Document | ShadowRoot;
|
|
||||||
const formId = input.getAttribute('form')!;
|
|
||||||
return doc.getElementById(formId) as HTMLFormElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fall back to the closest containing form
|
|
||||||
return input.closest('form');
|
|
||||||
},
|
|
||||||
assumeInteractionOn: ['click']
|
assumeInteractionOn: ['click']
|
||||||
});
|
});
|
||||||
|
|
||||||
private readonly hasSlotController = new HasSlotController(this, '[default]', 'prefix', 'suffix');
|
private readonly hasSlotController = new HasSlotController(this, '[default]', 'prefix', 'suffix');
|
||||||
private readonly localize = new LocalizeController(this);
|
private readonly localize = new LocalizeController(this);
|
||||||
|
|
||||||
|
|
|
@ -68,12 +68,16 @@ export class FormControlController implements ReactiveController {
|
||||||
this.options = {
|
this.options = {
|
||||||
form: input => {
|
form: input => {
|
||||||
// If there's a form attribute, use it to find the target form by id
|
// If there's a form attribute, use it to find the target form by id
|
||||||
if (input.hasAttribute('form') && input.getAttribute('form') !== '') {
|
// Controls may not always reflect the 'form' property. For example, `<sl-button>` doesn't reflect.
|
||||||
const root = input.getRootNode() as Document | ShadowRoot;
|
const formId = input.form;
|
||||||
const formId = input.getAttribute('form');
|
|
||||||
|
|
||||||
if (formId) {
|
if (formId) {
|
||||||
return root.getElementById(formId) as HTMLFormElement;
|
const root = input.getRootNode() as Document | ShadowRoot;
|
||||||
|
|
||||||
|
const form = root.getElementById(formId);
|
||||||
|
|
||||||
|
if (form) {
|
||||||
|
return form as HTMLFormElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ export function runFormControlBaseTests<T extends ShoelaceFormControl = Shoelace
|
||||||
// - `.checkValidity()`
|
// - `.checkValidity()`
|
||||||
// - `.reportValidity()`
|
// - `.reportValidity()`
|
||||||
// - `.setCustomValidity(msg)`
|
// - `.setCustomValidity(msg)`
|
||||||
|
// - `.getForm()`
|
||||||
//
|
//
|
||||||
function runAllValidityTests(
|
function runAllValidityTests(
|
||||||
tagName: string, //
|
tagName: string, //
|
||||||
|
@ -124,6 +125,27 @@ function runAllValidityTests(
|
||||||
const emittedEvents = checkEventEmissions(control, 'sl-invalid', () => control.reportValidity());
|
const emittedEvents = checkEventEmissions(control, 'sl-invalid', () => control.reportValidity());
|
||||||
expect(emittedEvents.length).to.equal(0);
|
expect(emittedEvents.length).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should find the correct form when given a form property', async () => {
|
||||||
|
const formId = 'test-form';
|
||||||
|
const form = await fixture(`<form id='${formId}'></form>`);
|
||||||
|
const control = await createControl();
|
||||||
|
expect(control.getForm()).to.equal(null);
|
||||||
|
control.form = 'test-form';
|
||||||
|
await control.updateComplete;
|
||||||
|
expect(control.getForm()).to.equal(form);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should find the correct form when given a form attribute', async () => {
|
||||||
|
const formId = 'test-form';
|
||||||
|
const form = await fixture(`<form id='${formId}'></form>`);
|
||||||
|
const control = await createControl();
|
||||||
|
expect(control.getForm()).to.equal(null);
|
||||||
|
control.setAttribute('form', 'test-form');
|
||||||
|
|
||||||
|
await control.updateComplete;
|
||||||
|
expect(control.getForm()).to.equal(form);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run special tests depending on component type
|
// Run special tests depending on component type
|
||||||
|
|
Ładowanie…
Reference in New Issue