diff --git a/src/list.ts b/src/list.ts index d6ea44d049..6bce0a8272 100644 --- a/src/list.ts +++ b/src/list.ts @@ -3,6 +3,7 @@ import { ActionContainer } from "./actions/container"; import { Action, BaseAction, IAction } from "./actions/action"; import { CssClassBuilder } from "./utils/cssClassBuilder"; import { ElementHelper } from "./element-helper"; +import { getFirstVisibleChild } from "./utils/utils"; export let defaultListCss = { root: "sv-list__container", @@ -203,8 +204,9 @@ export class ListModel extends ActionContainer if (event.key === "ArrowDown" || event.keyCode === 40) { const currentElement = (event.target).parentElement; const listElement = currentElement.parentElement.querySelector("ul"); - if (!!listElement && !!listElement.firstElementChild) { - ElementHelper.focusElement(listElement.firstElementChild); + const firstChild = getFirstVisibleChild(listElement); + if (!!listElement && !!firstChild) { + ElementHelper.focusElement(firstChild); event.preventDefault(); } } diff --git a/src/utils/utils.ts b/src/utils/utils.ts index b3cef4256e..c8143b99c6 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -301,6 +301,15 @@ function isContainerVisible(el: HTMLElement) { ); } +function getFirstVisibleChild(el: HTMLElement) { + let result; + for(let index = 0; index < el.children.length; index++) { + if(!result && getComputedStyle(el.children[index]).display !== "none") { + result = el.children[index]; + } + } + return result; +} function findParentByClassNames(element: HTMLElement, classNames: Array): Element { if (!!element) { if (classNames.every(className => !className || element.classList.contains(className))) { @@ -376,4 +385,5 @@ export { getOriginalEvent, preventDefaults, findParentByClassNames, + getFirstVisibleChild, }; diff --git a/testCafe/components/popup.ts b/testCafe/components/popup.ts index 11238d9d0f..6b2236119f 100644 --- a/testCafe/components/popup.ts +++ b/testCafe/components/popup.ts @@ -1,4 +1,4 @@ -import { url, initSurvey, frameworks } from "../helper"; +import { url, initSurvey, frameworks, getListItemByText } from "../helper"; import { Selector, ClientFunction } from "testcafe"; const title = "popup"; @@ -362,4 +362,34 @@ frameworks.forEach(async framework => { .expect(popupSelector.visible).ok() .expect(popupSelector.offsetHeight).within(popupHeight - 1, popupHeight + 1); }); + + test("list model", async t => { + await initSurvey(framework, json, { onGetQuestionTitleActions: (_, opt) => { + const getItems = (count, startIndex = 0) => { + const list = []; + for (let index = startIndex; index < count; index++) { + list[index - startIndex] = new window["Survey"].Action({ id: index, title: "item" + index, needSeparator: index % 4 == 1 }); + } + return list; + }; + const dropdownWithSearchAction = window["Survey"].createDropdownActionModel( + { title: "Long List", showTitle: true }, + { items: getItems(40), showPointer: true } + ); + opt.titleActions = [dropdownWithSearchAction]; + } }); + + const listItems = Selector(".sv-list__item").filterVisible(); + + await t + .click(Selector(".sv-action-bar-item")) + .expect(listItems.count).eql(40) + + .pressKey("1") + .expect(listItems.count).eql(13) + .expect(getListItemByText("item1").focused).notOk() + + .pressKey("down") + .expect(getListItemByText("item1").focused).ok(); + }); }); \ No newline at end of file