Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
### Fixed

- **Table**: Fixed resizing scrollable part of the table when table is resized.
- **SingleSelect**, **MultiSelect**: Check the validity state when `required` attribute is changed.

### Added

Expand Down
55 changes: 55 additions & 0 deletions dev/vscode-single-select/required-flag.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Required</title>
<script
type="module"
src="/node_modules/@vscode-elements/webview-playground/dist/index.js"
></script>
<script type="module" src="/dist/vscode-single-select/index.js"></script>
<script type="module" src="/dist/vscode-textfield/index.js"></script>
<script type="module" src="/dist/vscode-option/index.js"></script>
</head>
<body>
<vscode-demo>
<p>
<vscode-textfield
id="none-required-textfield-example"
></vscode-textfield>
</p>
<vscode-button id="required-textfield-button">Add Required</vscode-button>

<p>
<vscode-single-select id="none-required-combobox-example" combobox>
<vscode-option>Afghanistan</vscode-option>
<vscode-option>Albania</vscode-option>
</vscode-single-select>
</p>
<vscode-button id="required-combobox-button">Add Required</vscode-button>

<script type="module">
const textfield = document.querySelector(
'#none-required-textfield-example'
);
const textfieldButton = document.querySelector(
'#required-textfield-button'
);
textfieldButton.addEventListener('click', () => {
textfield.setAttribute('required', '');
});

const select = document.querySelector(
'#none-required-combobox-example'
);
const comboboxButton = document.querySelector(
'#required-combobox-button'
);
comboboxButton.addEventListener('click', () => {
select.setAttribute('required', '');
});
</script>
</vscode-demo>
</body>
</html>
16 changes: 15 additions & 1 deletion src/includes/vscode-select/vscode-select-base.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {html, render, nothing, TemplateResult} from 'lit';
import {html, render, nothing, TemplateResult, PropertyValues} from 'lit';
import {property, query, queryAssignedElements, state} from 'lit/decorators.js';
import {classMap} from 'lit/directives/class-map.js';
import {repeat} from 'lit/directives/repeat.js';
Expand Down Expand Up @@ -168,6 +168,18 @@ export class VscodeSelectBase extends VscElement {
this.removeEventListener('blur', this._onComponentBlur);
}

protected _firstUpdateCompleted = false;

protected override firstUpdated(_changedProperties: PropertyValues): void {
this._firstUpdateCompleted = true;
}

protected override willUpdate(changedProperties: PropertyValues): void {
if (changedProperties.has('required') && this._firstUpdateCompleted) {
this._manageRequired();
}
}

@state()
protected _activeIndex = -1;

Expand Down Expand Up @@ -242,6 +254,8 @@ export class VscodeSelectBase extends VscElement {
return this.combobox && !filterPatternExistsAsOption && filtered;
}

protected _manageRequired() {}

protected _setStateFromSlottedElements() {
const options: InternalOption[] = [];
let nextIndex = 0;
Expand Down
18 changes: 18 additions & 0 deletions src/vscode-multi-select/vscode-multi-select.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,24 @@ describe('vscode-multi-select', () => {
expect(li.classList.contains('disabled')).to.be.true;
});

it('checks validity when required property is changed', async () => {
const el = await fixture<VscodeMultiSelect>(
html`<vscode-multi-select combobox>
<vscode-option>Lorem</vscode-option>
<vscode-option>Ipsum</vscode-option>
</vscode-multi-select>`
);
const isValidBefore = el.checkValidity();

el.setAttribute('required', '');
await el.updateComplete;

const isValidAfter = el.checkValidity();

expect(isValidBefore).to.be.true;
expect(isValidAfter).to.be.false;
});

it('selects multiple options with keyboard');
it('selectedIndexes sync with values');
});
2 changes: 1 addition & 1 deletion src/vscode-multi-select/vscode-multi-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export class VscodeMultiSelect
}
}

private _manageRequired() {
protected override _manageRequired() {
const {value} = this;
if (value.length === 0 && this.required) {
this._internals.setValidity(
Expand Down
18 changes: 18 additions & 0 deletions src/vscode-single-select/vscode-single-select.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1235,6 +1235,24 @@ describe('vscode-single-select', () => {
}
);
});

it('checks validity when required property is changed', async () => {
const el = await fixture<VscodeSingleSelect>(
html`<vscode-single-select combobox>
<vscode-option>Lorem</vscode-option>
<vscode-option>Ipsum</vscode-option>
</vscode-single-select>`
);
const isValidBefore = el.checkValidity();

el.setAttribute('required', '');
await el.updateComplete;

const isValidAfter = el.checkValidity();

expect(isValidBefore).to.be.true;
expect(isValidAfter).to.be.false;
});
});

//keyboard navigation
Expand Down
2 changes: 1 addition & 1 deletion src/vscode-single-select/vscode-single-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ export class VscodeSingleSelect
}
}

private _manageRequired() {
protected override _manageRequired() {
const {value} = this;
if (value === '' && this.required) {
this._internals.setValidity(
Expand Down