kopia lustrzana https://github.com/shoelace-style/shoelace
Merge branch 'next' of https://github.com/shoelace-style/shoelace into rtl-for-older-browsers
commit
bb563a20c5
|
@ -16,6 +16,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti
|
|||
|
||||
- Updated all checks for directionality to use `this.localize.dir()` instead of `el.matches(:dir(rtl))` so older browsers don't error out [#2188]
|
||||
- Added Finnish translations [#2211]
|
||||
- Added the `.focus` function to `<sl-radio-group>` [#2192]
|
||||
- Fixed a bug with with `<sl-select>` not respecting its initial value. [#2204]
|
||||
- Fixed a bug with certain bundlers when using dynamic imports [#2210]
|
||||
- Fixed a bug in `<sl-textarea>` causing scroll jumping when using `resize="auto"` [#2182]
|
||||
|
|
|
@ -192,14 +192,7 @@ export default class SlRadioGroup extends ShoelaceElement implements ShoelaceFor
|
|||
}
|
||||
|
||||
private handleLabelClick() {
|
||||
const radios = this.getAllRadios();
|
||||
const checked = radios.find(radio => radio.checked);
|
||||
const radioToFocus = checked || radios[0];
|
||||
|
||||
// Move focus to the checked radio (or the first one if none are checked) when clicking the label
|
||||
if (radioToFocus) {
|
||||
radioToFocus.focus();
|
||||
}
|
||||
this.focus();
|
||||
}
|
||||
|
||||
private handleInvalid(event: Event) {
|
||||
|
@ -325,6 +318,20 @@ export default class SlRadioGroup extends ShoelaceElement implements ShoelaceFor
|
|||
this.formControlController.updateValidity();
|
||||
}
|
||||
|
||||
/** Sets focus on the radio-group. */
|
||||
public focus(options?: FocusOptions) {
|
||||
const radios = this.getAllRadios();
|
||||
const checked = radios.find(radio => radio.checked);
|
||||
const firstEnabledRadio = radios.find(radio => !radio.disabled);
|
||||
const radioToFocus = checked || firstEnabledRadio;
|
||||
|
||||
// Call focus for the checked radio
|
||||
// If no radio is checked, focus the first one that is not disabled
|
||||
if (radioToFocus) {
|
||||
radioToFocus.focus(options);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const hasLabelSlot = this.hasSlotController.test('label');
|
||||
const hasHelpTextSlot = this.hasSlotController.test('help-text');
|
||||
|
|
|
@ -300,6 +300,102 @@ describe('when a size is applied', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when handling focus', () => {
|
||||
const doAction = async (instance: SlRadioGroup, type: string) => {
|
||||
if (type === 'focus') {
|
||||
instance.focus();
|
||||
await instance.updateComplete;
|
||||
return;
|
||||
}
|
||||
|
||||
const label = instance.shadowRoot!.querySelector<HTMLLabelElement>('#label')!;
|
||||
label.click();
|
||||
await instance.updateComplete;
|
||||
};
|
||||
|
||||
// Tests for focus and label actions with radio buttons
|
||||
['focus', 'label'].forEach(actionType => {
|
||||
describe(`when using ${actionType}`, () => {
|
||||
it('should do nothing if all elements are disabled', async () => {
|
||||
const el = await fixture<SlRadioGroup>(html`
|
||||
<sl-radio-group>
|
||||
<sl-radio id="radio-0" value="0" disabled></sl-radio>
|
||||
<sl-radio id="radio-1" value="1" disabled></sl-radio>
|
||||
<sl-radio id="radio-2" value="2" disabled></sl-radio>
|
||||
<sl-radio id="radio-3" value="3" disabled></sl-radio>
|
||||
</sl-radio-group>
|
||||
`);
|
||||
|
||||
const validFocusHandler = sinon.spy();
|
||||
|
||||
Array.from(el.querySelectorAll<SlRadio>('sl-radio')).forEach(radio =>
|
||||
radio.addEventListener('sl-focus', validFocusHandler)
|
||||
);
|
||||
|
||||
expect(validFocusHandler).to.not.have.been.called;
|
||||
await doAction(el, actionType);
|
||||
expect(validFocusHandler).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('should focus the first radio that is enabled when the group receives focus', async () => {
|
||||
const el = await fixture<SlRadioGroup>(html`
|
||||
<sl-radio-group>
|
||||
<sl-radio id="radio-0" value="0" disabled></sl-radio>
|
||||
<sl-radio id="radio-1" value="1"></sl-radio>
|
||||
<sl-radio id="radio-2" value="2"></sl-radio>
|
||||
<sl-radio id="radio-3" value="3"></sl-radio>
|
||||
</sl-radio-group>
|
||||
`);
|
||||
|
||||
const invalidFocusHandler = sinon.spy();
|
||||
const validFocusHandler = sinon.spy();
|
||||
|
||||
const disabledRadio = el.querySelector('#radio-0')!;
|
||||
const validRadio = el.querySelector('#radio-1')!;
|
||||
|
||||
disabledRadio.addEventListener('sl-focus', invalidFocusHandler);
|
||||
validRadio.addEventListener('sl-focus', validFocusHandler);
|
||||
|
||||
expect(invalidFocusHandler).to.not.have.been.called;
|
||||
expect(validFocusHandler).to.not.have.been.called;
|
||||
|
||||
await doAction(el, actionType);
|
||||
|
||||
expect(invalidFocusHandler).to.not.have.been.called;
|
||||
expect(validFocusHandler).to.have.been.called;
|
||||
});
|
||||
|
||||
it('should focus the currently enabled radio when the group receives focus', async () => {
|
||||
const el = await fixture<SlRadioGroup>(html`
|
||||
<sl-radio-group value="2">
|
||||
<sl-radio id="radio-0" value="0" disabled></sl-radio>
|
||||
<sl-radio id="radio-1" value="1"></sl-radio>
|
||||
<sl-radio id="radio-2" value="2" checked></sl-radio>
|
||||
<sl-radio id="radio-3" value="3"></sl-radio>
|
||||
</sl-radio-group>
|
||||
`);
|
||||
|
||||
const invalidFocusHandler = sinon.spy();
|
||||
const validFocusHandler = sinon.spy();
|
||||
|
||||
const disabledRadio = el.querySelector('#radio-0')!;
|
||||
const validRadio = el.querySelector('#radio-2')!;
|
||||
|
||||
disabledRadio.addEventListener('sl-focus', invalidFocusHandler);
|
||||
validRadio.addEventListener('sl-focus', validFocusHandler);
|
||||
|
||||
expect(invalidFocusHandler).to.not.have.been.called;
|
||||
expect(validFocusHandler).to.not.have.been.called;
|
||||
|
||||
await doAction(el, actionType);
|
||||
|
||||
expect(invalidFocusHandler).to.not.have.been.called;
|
||||
expect(validFocusHandler).to.have.been.called;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the value changes', () => {
|
||||
it('should emit sl-change when toggled with the arrow keys', async () => {
|
||||
const radioGroup = await fixture<SlRadioGroup>(html`
|
||||
|
|
|
@ -601,6 +601,7 @@ describe('<sl-select>', () => {
|
|||
);
|
||||
const el = form.querySelector<SlSelect>('sl-select')!;
|
||||
|
||||
await aTimeout(10);
|
||||
expect(el.value).to.equal('');
|
||||
expect(new FormData(form).get('select')).equal('');
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue