diff --git a/dev/vscode-multi-select/a11y-combobox.html b/dev/vscode-multi-select/a11y-combobox.html new file mode 100644 index 000000000..f70e4e8c5 --- /dev/null +++ b/dev/vscode-multi-select/a11y-combobox.html @@ -0,0 +1,40 @@ + + + + + + VSCode Elements + + + + + + + +
+ + + Banana + Cherry + Apple + Strawberry + Lemon + Orange + + +
+ + diff --git a/dev/vscode-multi-select/a11y-select.html b/dev/vscode-multi-select/a11y-select.html new file mode 100644 index 000000000..0ddc3a1d4 --- /dev/null +++ b/dev/vscode-multi-select/a11y-select.html @@ -0,0 +1,40 @@ + + + + + + VSCode Elements + + + + + + + +
+ + + Banana + Cherry + Apple + Strawberry + Lemon + Orange + + +
+ + diff --git a/dev/vscode-multi-select/autofocus-combobox.html b/dev/vscode-multi-select/autofocus-combobox.html new file mode 100644 index 000000000..24876eaa9 --- /dev/null +++ b/dev/vscode-multi-select/autofocus-combobox.html @@ -0,0 +1,46 @@ + + + + + + multi combo + + + + + + + +
+ + + Lorem + Ipsum + Dolor + + + + +
+ + diff --git a/dev/vscode-multi-select/autofocus-select.html b/dev/vscode-multi-select/autofocus-select.html new file mode 100644 index 000000000..4222806a9 --- /dev/null +++ b/dev/vscode-multi-select/autofocus-select.html @@ -0,0 +1,51 @@ + + + + + + multi select + + + + + + + + +
+ + + Lorem + Ipsum + Dolor + + + + +
+ + diff --git a/dev/vscode-multi-select/combobox-suggestion-mode.html b/dev/vscode-multi-select/combobox-suggestion-mode.html index db92e9bdf..c8116b02d 100644 --- a/dev/vscode-multi-select/combobox-suggestion-mode.html +++ b/dev/vscode-multi-select/combobox-suggestion-mode.html @@ -224,14 +224,8 @@ Zimbabwe diff --git a/dev/vscode-single-select/combobox-mode/a11y.html b/dev/vscode-single-select/combobox-mode/a11y.html new file mode 100644 index 000000000..e1b73f59a --- /dev/null +++ b/dev/vscode-single-select/combobox-mode/a11y.html @@ -0,0 +1,40 @@ + + + + + + VSCode Elements + + + + + + + +
+ + + Banana + Cherry + Apple + Strawberry + Lemon + Orange + + +
+ + diff --git a/dev/vscode-single-select/combobox-mode/autofocus-combobox.html b/dev/vscode-single-select/combobox-mode/autofocus-combobox.html new file mode 100644 index 000000000..06bc96fb0 --- /dev/null +++ b/dev/vscode-single-select/combobox-mode/autofocus-combobox.html @@ -0,0 +1,46 @@ + + + + + + single combo + + + + + + + +
+ + + Lorem + Ipsum + Dolor + + + + +
+ + diff --git a/dev/vscode-single-select/combobox-suggestion-mode.html b/dev/vscode-single-select/combobox-mode/combobox-suggestion-mode.html similarity index 100% rename from dev/vscode-single-select/combobox-suggestion-mode.html rename to dev/vscode-single-select/combobox-mode/combobox-suggestion-mode.html diff --git a/dev/vscode-single-select/combobox.html b/dev/vscode-single-select/combobox-mode/combobox.html similarity index 100% rename from dev/vscode-single-select/combobox.html rename to dev/vscode-single-select/combobox-mode/combobox.html diff --git a/dev/vscode-single-select/deleting-value.html b/dev/vscode-single-select/combobox-mode/deleting-value.html similarity index 100% rename from dev/vscode-single-select/deleting-value.html rename to dev/vscode-single-select/combobox-mode/deleting-value.html diff --git a/dev/vscode-single-select/select-mode/a11y.html b/dev/vscode-single-select/select-mode/a11y.html new file mode 100644 index 000000000..ad8854a19 --- /dev/null +++ b/dev/vscode-single-select/select-mode/a11y.html @@ -0,0 +1,40 @@ + + + + + + VSCode Elements + + + + + + + +
+ + + Banana + Cherry + Apple + Strawberry + Lemon + Orange + + +
+ + diff --git a/dev/vscode-single-select/select-mode/autofocus-select.html b/dev/vscode-single-select/select-mode/autofocus-select.html new file mode 100644 index 000000000..cf5d9e7b9 --- /dev/null +++ b/dev/vscode-single-select/select-mode/autofocus-select.html @@ -0,0 +1,51 @@ + + + + + + single select + + + + + + + + +
+ + + Lorem + Ipsum + Dolor + + + + +
+ + diff --git a/dev/vscode-single-select/basic-example.html b/dev/vscode-single-select/select-mode/basic-example.html similarity index 71% rename from dev/vscode-single-select/basic-example.html rename to dev/vscode-single-select/select-mode/basic-example.html index 771c62a57..e69681667 100644 --- a/dev/vscode-single-select/basic-example.html +++ b/dev/vscode-single-select/select-mode/basic-example.html @@ -26,12 +26,22 @@
- + Lorem Ipsum Dolor + Sit + +
diff --git a/dev/vscode-single-select/default-empty.html b/dev/vscode-single-select/select-mode/default-empty.html similarity index 100% rename from dev/vscode-single-select/default-empty.html rename to dev/vscode-single-select/select-mode/default-empty.html diff --git a/dev/vscode-single-select/description.html b/dev/vscode-single-select/select-mode/description.html similarity index 100% rename from dev/vscode-single-select/description.html rename to dev/vscode-single-select/select-mode/description.html diff --git a/dev/vscode-single-select/select-mode/disabled-options.html b/dev/vscode-single-select/select-mode/disabled-options.html new file mode 100644 index 000000000..d01da9426 --- /dev/null +++ b/dev/vscode-single-select/select-mode/disabled-options.html @@ -0,0 +1,55 @@ + + + + + + VSCode Elements + + + + + + + +
+ + + Lorem + Ipsum + Dolor + Sit + + + + +
+ Native select + + +
+
+ + diff --git a/dev/vscode-single-select/dispatch-invalid-event.html b/dev/vscode-single-select/select-mode/dispatch-invalid-event.html similarity index 100% rename from dev/vscode-single-select/dispatch-invalid-event.html rename to dev/vscode-single-select/select-mode/dispatch-invalid-event.html diff --git a/dev/vscode-single-select/element-value.html b/dev/vscode-single-select/select-mode/element-value.html similarity index 100% rename from dev/vscode-single-select/element-value.html rename to dev/vscode-single-select/select-mode/element-value.html diff --git a/dev/vscode-single-select/empty-label.html b/dev/vscode-single-select/select-mode/empty-label.html similarity index 100% rename from dev/vscode-single-select/empty-label.html rename to dev/vscode-single-select/select-mode/empty-label.html diff --git a/dev/vscode-single-select/initial-form-value.html b/dev/vscode-single-select/select-mode/initial-form-value.html similarity index 100% rename from dev/vscode-single-select/initial-form-value.html rename to dev/vscode-single-select/select-mode/initial-form-value.html diff --git a/dev/vscode-single-select/disabled-options.html b/dev/vscode-single-select/select-mode/large-list.html similarity index 97% rename from dev/vscode-single-select/disabled-options.html rename to dev/vscode-single-select/select-mode/large-list.html index 1e6969969..01719afbf 100644 --- a/dev/vscode-single-select/disabled-options.html +++ b/dev/vscode-single-select/select-mode/large-list.html @@ -26,15 +26,15 @@
- + Afghanistan Albania Algeria - Andorra + Andorra Angola Antigua and Barbuda - Argentina - Armenia + Argentina + Armenia Australia Austria Azerbaijan @@ -228,6 +228,10 @@ sl.addEventListener('change', () => { console.log(sl.value); }); + + sl.addEventListener('vsc-single-select-create-option', (ev) => { + console.log(ev); + }); @@ -238,11 +242,11 @@ - + - - + + diff --git a/dev/vscode-single-select/open-prop.html b/dev/vscode-single-select/select-mode/open-prop.html similarity index 100% rename from dev/vscode-single-select/open-prop.html rename to dev/vscode-single-select/select-mode/open-prop.html diff --git a/dev/vscode-single-select/open-when-enter-key-pressed.html b/dev/vscode-single-select/select-mode/open-when-enter-key-pressed.html similarity index 100% rename from dev/vscode-single-select/open-when-enter-key-pressed.html rename to dev/vscode-single-select/select-mode/open-when-enter-key-pressed.html diff --git a/dev/vscode-single-select/option-with-empty-value.html b/dev/vscode-single-select/select-mode/option-with-empty-value.html similarity index 100% rename from dev/vscode-single-select/option-with-empty-value.html rename to dev/vscode-single-select/select-mode/option-with-empty-value.html diff --git a/dev/vscode-single-select/required-flag.html b/dev/vscode-single-select/select-mode/required-flag.html similarity index 100% rename from dev/vscode-single-select/required-flag.html rename to dev/vscode-single-select/select-mode/required-flag.html diff --git a/dev/vscode-single-select/select-mode/scroll-to-the-selected-option.html b/dev/vscode-single-select/select-mode/scroll-to-the-selected-option.html new file mode 100644 index 000000000..32cc3f1d4 --- /dev/null +++ b/dev/vscode-single-select/select-mode/scroll-to-the-selected-option.html @@ -0,0 +1,54 @@ + + + + + + VSCode Elements + + + + + + + +
+ + + Afghanistan + Albania + Algeria + Andorra + Angola + Antigua and Barbuda + Argentina + Armenia + Australia + Austria + Azerbaijan + Bahamas + Bahrain + Bangladesh + Barbados + Belarus + Belgium + Belize + Benin + Bhutan + + +
+ + diff --git a/dev/vscode-single-select/set-empty-value-before-options.html b/dev/vscode-single-select/select-mode/set-empty-value-before-options.html similarity index 100% rename from dev/vscode-single-select/set-empty-value-before-options.html rename to dev/vscode-single-select/select-mode/set-empty-value-before-options.html diff --git a/dev/vscode-single-select/set-value-before-options.html b/dev/vscode-single-select/select-mode/set-value-before-options.html similarity index 100% rename from dev/vscode-single-select/set-value-before-options.html rename to dev/vscode-single-select/select-mode/set-value-before-options.html diff --git a/dev/vscode-single-select/sync-options.html b/dev/vscode-single-select/select-mode/sync-options.html similarity index 100% rename from dev/vscode-single-select/sync-options.html rename to dev/vscode-single-select/select-mode/sync-options.html diff --git a/eslint.config.mjs b/eslint.config.mjs index 4ac79d134..46af95780 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -38,6 +38,7 @@ export default [ }, rules: { + 'no-console': 'error', 'no-unexpected-multiline': 'off', '@typescript-eslint/indent': 'off', '@typescript-eslint/explicit-function-return-type': 'off', diff --git a/src/includes/VscElement.ts b/src/includes/VscElement.ts index 66d5f3690..126612226 100644 --- a/src/includes/VscElement.ts +++ b/src/includes/VscElement.ts @@ -38,6 +38,7 @@ export const customElement = (tagName: string) => { let message = ''; if (!anotherVersion) { + // eslint-disable-next-line no-console console.warn( tagName, 'is already registered by an unknown custom element handler class.' @@ -53,6 +54,7 @@ export const customElement = (tagName: string) => { 'is already registered by the same version of VSCode Elements. '; } + // eslint-disable-next-line no-console console.warn( `[VSCode Elements] ${tagName} ${message}\nTo suppress this warning, set window.${CONFIG_KEY} to true` ); diff --git a/src/includes/vscode-select/OptionListController.ts b/src/includes/vscode-select/OptionListController.ts new file mode 100644 index 000000000..1fcb27991 --- /dev/null +++ b/src/includes/vscode-select/OptionListController.ts @@ -0,0 +1,475 @@ +import {ReactiveController, ReactiveControllerHost} from 'lit'; +import {FilterMethod, InternalOption, Option} from './types'; +import { + containsSearch, + fuzzySearch, + SearchResult, + startsWithPerTermSearch, + startsWithSearch, +} from './helpers'; + +export class OptionListController implements ReactiveController { + private _activeIndex = -1; + private _host: ReactiveControllerHost; + private _options: InternalOption[] = []; + private _filterPattern = ''; + private _filterMethod: FilterMethod = 'fuzzy'; + private _combobox = false; + private _indexByValue: Map = new Map(); + private _indexByLabel: Map = new Map(); + private _selectedIndex = -1; + private _selectedIndexes: Set = new Set(); + private _multiSelect = false; + private _numOfVisibleOptions = 0; + + constructor(host: ReactiveControllerHost) { + (this._host = host).addController(this); + } + + hostConnected(): void {} + + //#region getters/setters + + get activeIndex(): number { + return this._activeIndex; + } + + set activeIndex(index: number) { + this._activeIndex = index; + this._host.requestUpdate(); + } + + get relativeActiveIndex(): number { + return this._options[this._activeIndex]?.filteredIndex ?? -1; + } + + set comboboxMode(enabled: boolean) { + this._combobox = enabled; + this._host.requestUpdate(); + } + + get comboboxMode() { + return this._combobox; + } + + get multiSelect() { + return this._multiSelect; + } + + set multiSelect(multiSelect: boolean) { + this._selectedIndex = -1; + this._selectedIndexes.clear(); + this._multiSelect = multiSelect; + this._host.requestUpdate(); + } + + get selectedIndex() { + return this._selectedIndex; + } + + set selectedIndex(index: number) { + if (this._selectedIndex !== -1) { + this._options[this._selectedIndex].selected ??= false; + } + + const op = this.getOptionByIndex(index); + + this._selectedIndex = op ? index : -1; + this._host.requestUpdate(); + } + + get selectedIndexes() { + return Array.from(this._selectedIndexes); + } + + set selectedIndexes(value: number[]) { + this._selectedIndexes.forEach((v) => { + this._options[v].selected = false; + }); + + this._selectedIndexes = new Set(value); + + value.forEach((v) => { + if (this._options[v] !== undefined) { + this._options[v].selected = true; + } + }); + + this._host.requestUpdate(); + } + + set value(newValue: string | string[]) { + if (this._multiSelect) { + const valueList = (newValue as string[]) + .map((v) => this._indexByValue.get(v)) + .filter((v) => v !== undefined); + + this._selectedIndexes = new Set(valueList); + } else { + this._selectedIndex = this._indexByValue.get(newValue as string) ?? -1; + } + this._host.requestUpdate(); + } + + get value(): string | string[] { + if (this._multiSelect) { + return this._selectedIndexes.size > 0 + ? Array.from(this._selectedIndexes).map((v) => this._options[v].value) + : []; + } else { + return this._selectedIndex > -1 + ? this._options[this._selectedIndex].value + : ''; + } + } + + set multiSelectValue(newValue: string[]) { + const valueList = (newValue as string[]) + .map((v) => this._indexByValue.get(v)) + .filter((v) => v !== undefined); + + this._selectedIndexes = new Set(valueList); + } + + get multiSelectValue(): string[] { + return this._selectedIndexes.size > 0 + ? Array.from(this._selectedIndexes).map((v) => this._options[v].value) + : []; + } + + get filterPattern() { + return this._filterPattern; + } + + set filterPattern(pattern: string) { + if (pattern !== this._filterPattern) { + this._filterPattern = pattern; + this._updateState(); + } + } + + get filterMethod(): FilterMethod { + return this._filterMethod; + } + + set filterMethod(method: FilterMethod) { + if (method !== this._filterMethod) { + this._filterMethod = method; + this._updateState(); + } + } + + get options(): InternalOption[] { + return this._options; + } + + get numOfVisibleOptions() { + return this._numOfVisibleOptions; + } + + get numOptions() { + return this._options.length; + } + + //#endregion + + //#region public functions + + populate(options: Option[]) { + this._indexByValue.clear(); + this._indexByLabel.clear(); + + this._options = options.map((op, index) => { + this._indexByValue.set(op.value ?? '', index); + this._indexByLabel.set(op.label ?? '', index); + + return { + description: op.description ?? '', + disabled: op.disabled ?? false, + label: op.label ?? '', + selected: op.selected ?? false, + value: op.value ?? '', + index, + filteredIndex: index, + ranges: [], + visible: true, + }; + }); + + this._numOfVisibleOptions = this._options.length; + } + + add(option: Option) { + const nextIndex = this._options.length; + const {description, disabled, label, selected, value} = option; + let visible = true; + let ranges: [number, number][] = []; + + if (this._combobox && this._filterPattern !== '') { + const res = this._searchByPattern(label ?? ''); + visible = res.match; + ranges = res.ranges; + } + + this._indexByValue.set(value ?? '', nextIndex); + this._indexByLabel.set(label ?? '', nextIndex); + + if (selected) { + this._selectedIndex = nextIndex; + this._selectedIndexes.add(nextIndex); + this._activeIndex = nextIndex; + } + + this._options.push({ + index: nextIndex, + filteredIndex: nextIndex, + description: description ?? '', + disabled: disabled ?? false, + label: label ?? '', + selected: selected ?? false, + value: value ?? '', + visible, + ranges, + }); + + if (visible) { + this._numOfVisibleOptions += 1; + } + } + + clear() { + this._options = []; + this._indexByValue.clear(); + this._indexByLabel.clear(); + this._numOfVisibleOptions = 0; + } + + getIsIndexSelected(index: number) { + if (this._multiSelect) { + return this._selectedIndexes.has(index); + } else { + return this._selectedIndex === index; + } + } + + expandMultiSelection(values: string[]) { + values.forEach((v) => { + const foundIndex = this._indexByValue.get(v) ?? -1; + + if (foundIndex !== -1) { + this._selectedIndexes.add(foundIndex); + } + }); + + this._host.requestUpdate(); + } + + toggleActiveMultiselectOption() { + const activeOption = this._options[this._activeIndex] ?? null; + + if (!activeOption) { + return; + } + + const checked = this._selectedIndexes.has(activeOption.index); + + if (checked) { + this._selectedIndexes.delete(activeOption.index); + } else { + this._selectedIndexes.add(activeOption.index); + } + + this._host.requestUpdate(); + } + + toggleOptionSelected(optIndex: number) { + const checked = this._selectedIndexes.has(optIndex); + this._options[optIndex].selected = !this._options[optIndex].selected; + + if (checked) { + this._selectedIndexes.delete(optIndex); + } else { + this._selectedIndexes.add(optIndex); + } + + this._host.requestUpdate(); + } + + getActiveOption(): InternalOption | null { + return this._options[this._activeIndex] ?? null; + } + + getSelectedOption(): InternalOption | null { + return this._options[this._selectedIndex] ?? null; + } + + getOptionByIndex(index: number) { + return this._options[index] ?? null; + } + + findOptionIndex(value: string) { + return this._indexByValue.get(value) ?? -1; + } + + getOptionByValue( + value: string, + includeHiddenOptions = false + ): InternalOption | null { + const index = this._indexByValue.get(value) ?? -1; + + if (index === -1) { + return null; + } + + if (!includeHiddenOptions) { + return this._options[index].visible ? this._options[index] : null; + } + + return this._options[index]; + } + + getOptionByLabel(label: string) { + const index = this._indexByLabel.get(label) ?? -1; + + if (index === -1) { + return null; + } + + return this._options[index]; + } + + next(fromIndex?: number): InternalOption | null { + const from = fromIndex ?? this._activeIndex; + let nextIndex = -1; + + for (let i = from + 1; i < this._options.length; i++) { + if ( + this._options[i] && + !this._options[i].disabled && + this._options[i].visible + ) { + nextIndex = i; + break; + } + } + + return nextIndex > -1 ? this._options[nextIndex] : null; + } + + prev(fromIndex?: number): InternalOption | null { + const from = fromIndex ?? this._activeIndex; + + let prevIndex = -1; + + for (let i = from - 1; i >= 0; i--) { + if ( + this._options[i] && + !this._options[i].disabled && + this._options[i].visible + ) { + prevIndex = i; + break; + } + } + + return prevIndex > -1 ? this._options[prevIndex] : null; + } + + activateDefault() { + if (this._multiSelect) { + if (this._selectedIndexes.size > 0) { + const indexes = this._selectedIndexes.values(); + const first = indexes.next(); + this._activeIndex = first.value ? first.value : 0; + } + } else { + if (this._selectedIndex > -1) { + this._activeIndex = this._selectedIndex; + } else { + this._activeIndex = 0; + } + } + + this._host.requestUpdate(); + } + + selectAll() { + if (!this._multiSelect) { + return; + } + + this._options.forEach((_, i) => { + this._options[i].selected = true; + this._selectedIndexes.add(i); + }); + + this._host.requestUpdate(); + } + + selectNone() { + if (!this._multiSelect) { + return; + } + + this._options.forEach((_, i) => { + this._options[i].selected = false; + }); + this._selectedIndexes.clear(); + + this._host.requestUpdate(); + } + + //#endregion + + //#region private functions + + private _searchByPattern(text: string) { + let result: SearchResult; + + switch (this._filterMethod) { + case 'startsWithPerTerm': + result = startsWithPerTermSearch(text, this._filterPattern); + break; + case 'startsWith': + result = startsWithSearch(text, this._filterPattern); + break; + case 'contains': + result = containsSearch(text, this._filterPattern); + break; + default: + result = fuzzySearch(text, this._filterPattern); + } + + return result; + } + + private _updateState() { + if (!this._combobox || this._filterPattern === '') { + this._options.forEach((_, i) => { + this._options[i].visible = true; + this._options[i].ranges = []; + }); + this._numOfVisibleOptions = this._options.length; + } else { + let filteredListNextIndex = -1; + this._numOfVisibleOptions = 0; + + this._options.forEach(({label}, i) => { + const result = this._searchByPattern(label); + this._options[i].visible = result.match; + this._options[i].ranges = result.ranges; + this._options[i].filteredIndex = result.match + ? ++filteredListNextIndex + : -1; + + if (result.match) { + this._numOfVisibleOptions += 1; + } + }); + } + + this._host.requestUpdate(); + } + + //#endregion +} diff --git a/src/includes/vscode-select/helpers.ts b/src/includes/vscode-select/helpers.ts index 4161a3a83..1bef08426 100644 --- a/src/includes/vscode-select/helpers.ts +++ b/src/includes/vscode-select/helpers.ts @@ -1,5 +1,5 @@ import {html, TemplateResult} from 'lit'; -import {InternalOption, SearchMethod} from './types.js'; +import {InternalOption, FilterMethod} from './types.js'; export type SearchResult = { match: boolean; @@ -112,7 +112,7 @@ export const fuzzySearch = (subject: string, pattern: string): SearchResult => { export const filterOptionsByPattern = ( list: InternalOption[], pattern: string, - method: SearchMethod + method: FilterMethod ): InternalOption[] => { const filtered: InternalOption[] = []; diff --git a/src/includes/vscode-select/styles.ts b/src/includes/vscode-select/styles.ts index bf5d0d028..742c08a20 100644 --- a/src/includes/vscode-select/styles.ts +++ b/src/includes/vscode-select/styles.ts @@ -68,7 +68,6 @@ export default [ line-height: 16px; margin: 2px; padding: 2px 3px; - text-transform: uppercase; white-space: nowrap; } @@ -164,6 +163,7 @@ export default [ border-style: solid; border-width: 1px; box-sizing: border-box; + display: none; left: 0; padding-bottom: 2px; position: absolute; @@ -172,6 +172,10 @@ export default [ z-index: var(--dropdown-z-index, 2); } + .dropdown.open { + display: block; + } + :host([position='above']) .dropdown { border-radius: 3px 3px 0 0; bottom: 26px; @@ -309,37 +313,29 @@ export default [ } .checkbox-icon { - background-color: var(--vscode-settings-checkboxBackground, #313131); - border: 1px solid currentColor; + align-items: center; + background-color: var(--vscode-checkbox-background, #313131); + border: 1px solid var(--vscode-checkbox-border); border-radius: 2px; box-sizing: border-box; - height: 14px; + color: var(--vscode-checkbox-foreground); + display: inline-flex; + height: 15px; + justify-content: center; margin-right: 5px; overflow: hidden; position: relative; - width: 14px; + width: 15px; } - .checkbox-icon.checked:before, - .checkbox-icon.checked:after { - content: ''; - display: block; - height: 5px; - position: absolute; - transform: rotate(-45deg); - width: 10px; - } - - .checkbox-icon.checked:before { - background-color: var(--vscode-foreground, #cccccc); - left: 1px; - top: 2.5px; + .checkbox-icon svg { + display: none; + height: 13px; + width: 13px; } - .checkbox-icon.checked:after { - background-color: var(--vscode-settings-checkboxBackground, #313131); - left: 1px; - top: -0.5px; + .checkbox-icon.checked svg { + display: block; } .dropdown-controls { diff --git a/src/includes/vscode-select/template-elements.ts b/src/includes/vscode-select/template-elements.ts index a58e1c9e2..bbe3525af 100644 --- a/src/includes/vscode-select/template-elements.ts +++ b/src/includes/vscode-select/template-elements.ts @@ -1,4 +1,4 @@ -import {html} from 'lit'; +import {html, svg} from 'lit'; export const chevronDownIcon = html` @@ -17,3 +17,17 @@ export const chevronDownIcon = html` `; + +export const checkIcon = svg` + +`; diff --git a/src/includes/vscode-select/types.ts b/src/includes/vscode-select/types.ts index 93523ef3a..e25a5dff5 100644 --- a/src/includes/vscode-select/types.ts +++ b/src/includes/vscode-select/types.ts @@ -1,17 +1,21 @@ export interface Option { - label: string; - value: string; - description: string; - selected: boolean; - disabled: boolean; + label?: string; + value?: string; + description?: string; + selected?: boolean; + disabled?: boolean; } -export interface InternalOption extends Option { +export interface InternalOption extends Required