Skip to content

Commit

Permalink
fix: uui-combobox should correctly handle the active item (#682)
Browse files Browse the repository at this point in the history
* use expand symbol

* use option value as anchor instead of index
  • Loading branch information
JesmoDev authored Dec 14, 2023
1 parent 985bfaf commit a438b03
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 50 deletions.
73 changes: 39 additions & 34 deletions packages/uui-combobox-list/lib/uui-combobox-list.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,8 @@ export class UUIComboboxListElement extends LitElement {
@state()
private _value: FormDataEntryValue | FormData = '';

private __activeElement: UUIComboboxListOptionElement | undefined;
private get _activeElement(): UUIComboboxListOptionElement | undefined {
return this.__activeElement;
}
private set _activeElement(el: UUIComboboxListOptionElement | undefined) {
if (this.__activeElement) {
this.__activeElement.active = false;
}
if (el) {
el.active = true;
this.__activeElement = el;
}
}
@state()
private _activeElementValue: string | null = null;

private _selectedElement: UUIComboboxListOptionElement | undefined;

Expand Down Expand Up @@ -129,30 +118,35 @@ export class UUIComboboxListElement extends LitElement {
}

private _onSlotChange = () => {
this._activeElement = undefined;
// Get index from first active, remove active from the rest.
for (let i = 0; i < this._activeOptions.length; i++) {
if (i === 0) {
this._activeElement = this._activeOptions[i];
} else {
this._activeOptions[i].active = false;
}
}
this.#updateActiveElement();

this._updateSelection();
this.dispatchEvent(
new UUIComboboxListEvent(UUIComboboxListEvent.INNER_SLOT_CHANGE)
);
};

#updateActiveElement() {
for (let i = 0; i < this._activeOptions.length; i++) {
this._activeOptions[i].active = false;
}

const activeElement = this._getActiveElement;
if (activeElement) {
activeElement.active = true;
} else {
this._goToIndex(0);
}
}

private _onSelected = (e: Event) => {
if (this._selectedElement) {
this._selectedElement.selected = false;
this._selectedElement.active = false;
this._selectedElement = undefined;
}
this._selectedElement = e.composedPath()[0] as UUIComboboxListOptionElement;
this._activeElement = this._selectedElement;

this.value = this._selectedElement.value || '';
this.displayValue = this._selectedElement.displayValue || '';
Expand All @@ -161,37 +155,48 @@ export class UUIComboboxListElement extends LitElement {
};
private _onDeselected = (e: Event) => {
const el = e.composedPath()[0] as UUIComboboxListOptionElement;
if (this._activeElement === el) {
this._activeElement = undefined;
}
if (this._selectedElement === el) {
this.value = '';
this.displayValue = '';
this.dispatchEvent(new UUIComboboxListEvent(UUIComboboxListEvent.CHANGE));
}
};

private _getActiveIndex(): number {
return this._activeElement
? this._options.indexOf(this._activeElement)
: -1;
private get _getActiveIndex(): number {
if (this._activeElementValue === null) return -1;

return this._options.findIndex(
element => element.value === this._activeElementValue
);
}

private get _getActiveElement() {
if (this._activeElementValue === null) return null;

return this._options.find(
element => element.value === this._activeElementValue
);
}

private _moveIndex = (distance: number) => {
const newIndex = Math.min(
Math.max(this._getActiveIndex() + distance, 0),
Math.max(this._getActiveIndex + distance, 0),
this._options.length - 1
);

this._goToIndex(newIndex);
};

private _goToIndex(index: number) {
if (this._options.length === 0) return;

index = Math.min(Math.max(index, 0), this._options.length - 1); // Makes sure the index stays within array length
this._activeElement = this._options[index];
const activeElement = this._options[index];
this._activeElementValue = activeElement.value;
this.#updateActiveElement();

if (this._activeElement) {
this._activeElement.scrollIntoView({
if (activeElement) {
activeElement.scrollIntoView({
behavior: 'auto',
block: 'nearest',
inline: 'nearest',
Expand Down Expand Up @@ -222,7 +227,7 @@ export class UUIComboboxListElement extends LitElement {

case 'Enter': {
e.preventDefault();
this._activeElement?.click();
this._getActiveElement?.click();
break;
}

Expand Down
26 changes: 11 additions & 15 deletions packages/uui-combobox/lib/uui-combobox.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export class UUIComboboxElement extends FormControlMixin(LitElement) {
demandCustomElement(this, 'uui-combobox-list');
demandCustomElement(this, 'uui-scroll-container');
demandCustomElement(this, 'uui-popover-container');
demandCustomElement(this, 'uui-symbol-expand');
}

disconnectedCallback(): void {
Expand Down Expand Up @@ -286,17 +287,14 @@ export class UUIComboboxElement extends FormControlMixin(LitElement) {
@input=${this.#onInput}
@keydown=${this.#onKeyDown}>
<slot name="input-prepend" slot="prepend"></slot>
${this.disabled ? '' : this.#renderClearButton()} ${this.#renderCaret()}
${this.disabled ? '' : this.#renderClearButton()}
<div id="expand-symbol-wrapper" slot="append">
<uui-symbol-expand .open=${this._isOpen}></uui-symbol-expand>
</div>
<slot name="input-append" slot="append"></slot>
</uui-input>`;
};

#renderCaret = () => {
return html`<svg id="caret" slot="append" viewBox="0 0 512 512">
<path d="M 255.125 400.35 L 88.193 188.765 H 422.055 Z"></path>
</svg>`;
};

#renderClearButton = () => {
return this.value || this.search
? html`<uui-button
Expand Down Expand Up @@ -361,6 +359,12 @@ export class UUIComboboxElement extends FormControlMixin(LitElement) {
width: 100%;
max-height: var(--uui-combobox-popover-max-height, 500px);
}
#expand-symbol-wrapper {
height: 100%;
padding-right: var(--uui-size-space-3);
display: flex;
justify-content: center;
}
#dropdown {
overflow: hidden;
Expand All @@ -377,14 +381,6 @@ export class UUIComboboxElement extends FormControlMixin(LitElement) {
box-shadow: var(--uui-shadow-depth-3);
}
#caret {
margin-right: var(--uui-size-3, 9px);
display: flex;
width: 1.15em;
flex-shrink: 0;
margin-top: -1px;
}
:host([disabled]) #caret {
fill: var(--uui-color-disabled-contrast);
}
Expand Down
1 change: 1 addition & 0 deletions packages/uui-combobox/lib/uui-combobox.story.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '@umbraco-ui/uui-icon/lib';
import '@umbraco-ui/uui-input/lib';
import '@umbraco-ui/uui-button/lib';
import '@umbraco-ui/uui-popover-container/lib';
import '@umbraco-ui/uui-symbol-expand';

import '.';
import './uui-combobox-async-example';
Expand Down
3 changes: 2 additions & 1 deletion packages/uui-combobox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"@umbraco-ui/uui-combobox-list": "1.6.0-rc.1",
"@umbraco-ui/uui-icon": "1.6.0-rc.1",
"@umbraco-ui/uui-scroll-container": "1.6.0-rc.1",
"@umbraco-ui/uui-popover-container": "1.6.0-rc.1"
"@umbraco-ui/uui-popover-container": "1.6.0-rc.1",
"@umbraco-ui/uui-symbol-expand": "1.6.0-rc.1"
},
"scripts": {
"build": "npm run analyze && tsc --build --force && rollup -c rollup.config.js",
Expand Down

0 comments on commit a438b03

Please sign in to comment.