Allow keyboard nav to cycle to top and bottom of full list. Fix font weight and collapse alignment.

This commit is contained in:
Donnie 2020-11-16 12:41:12 -08:00
parent 366bea4344
commit 28405f6ddf
2 changed files with 44 additions and 23 deletions

View File

@ -49,6 +49,7 @@ export class HaClickableListItem extends ListItem {
align-items: center; align-items: center;
padding-left: var(--mdc-list-side-padding, 20px); padding-left: var(--mdc-list-side-padding, 20px);
padding-right: var(--mdc-list-side-padding, 20px); padding-right: var(--mdc-list-side-padding, 20px);
font-weight: 500;
} }
`, `,
]; ];

View File

@ -187,10 +187,10 @@ class HaSidebar extends LitElement {
@internalProperty() private _renderEmptySortable = false; @internalProperty() private _renderEmptySortable = false;
@query("div.ha-scrollbar mwc-list.main-panels", false) @query("div.ha-scrollbar mwc-list.main-panels", false)
private _standardPanelList?: List; private _standardPanelList!: List;
@query("div.ha-scrollbar mwc-list.utility-panels", false) @query("div.ha-scrollbar mwc-list.utility-panels", false)
private _utilityPanelList?: List; private _utilityPanelList!: List;
private _mouseLeaveTimeout?: number; private _mouseLeaveTimeout?: number;
@ -720,29 +720,48 @@ class HaSidebar extends LitElement {
return -1; return -1;
} }
private _listboxKeydown(ev: KeyboardEvent) { private _getCurrentListPosition(ev: KeyboardEvent) {
const [beforeSpacer] = computePanels( return {
index: this._getIndexOfTarget(ev),
list: ev.currentTarget as List,
};
}
private _selectNextItem(ev: KeyboardEvent) {
const [beforeSpacer, afterSpacer] = computePanels(
this.hass.panels, this.hass.panels,
this.hass.defaultPanel, this.hass.defaultPanel,
this._panelOrder, this._panelOrder,
this._hiddenPanels this._hiddenPanels
); );
const curIndex = this._getIndexOfTarget(ev); const { index, list } = this._getCurrentListPosition(ev);
const curList = ev.currentTarget as List;
if (ev.code === "ArrowDown" && curList === this._standardPanelList) { if (list === this._standardPanelList && index === beforeSpacer.length - 1) {
const isLastItem = curIndex === beforeSpacer.length - 1; this._setFocusPanelList(this._utilityPanelList, "top");
} else if (
list === this._utilityPanelList &&
index === afterSpacer.length - 1
) {
this._setFocusPanelList(this._standardPanelList, "top");
}
}
if (isLastItem) { private _selectPreviousItem(ev: KeyboardEvent) {
this._setFocusFirstListItem(); const { index, list } = this._getCurrentListPosition(ev);
}
} else if (ev.code === "ArrowUp" && curList === this._utilityPanelList) {
const isFirstItem = curIndex === 0;
if (isFirstItem) { if (list === this._standardPanelList && index === 0) {
this._setFocusLastListItem(); this._setFocusPanelList(this._utilityPanelList, "bottom");
} } else if (list === this._utilityPanelList && index === 0) {
this._setFocusPanelList(this._standardPanelList, "bottom");
}
}
private _listboxKeydown(ev: KeyboardEvent) {
if (ev.code === "ArrowDown") {
this._selectNextItem(ev);
} else if (ev.code === "ArrowUp") {
this._selectPreviousItem(ev);
} else if (ev.code === "Enter") { } else if (ev.code === "Enter") {
(ev.target as ListItem)?.shadowRoot?.querySelector("a")?.click(); (ev.target as ListItem)?.shadowRoot?.querySelector("a")?.click();
} }
@ -750,13 +769,14 @@ class HaSidebar extends LitElement {
this._recentKeydownActiveUntil = new Date().getTime() + 100; this._recentKeydownActiveUntil = new Date().getTime() + 100;
} }
private _setFocusFirstListItem() { private _setFocusPanelList(list: List, position: "top" | "bottom") {
this._utilityPanelList?.focusItemAtIndex(0); let index = 0;
}
private _setFocusLastListItem() { if (position === "bottom") {
const list = this._standardPanelList; index = list.querySelectorAll("ha-clickable-list-item").length - 1;
list?.focusItemAtIndex(list?.items.length - 1); }
list.focusItemAtIndex(index);
} }
private _showTooltip(item) { private _showTooltip(item) {
@ -910,7 +930,7 @@ class HaSidebar extends LitElement {
} }
ha-clickable-list-item { ha-clickable-list-item {
margin: 4px 8px; margin: 4px;
border-radius: 4px; border-radius: 4px;
height: 40px; height: 40px;
--mdc-list-side-padding: 12px; --mdc-list-side-padding: 12px;