@@ -1296,7 +1296,7 @@ describe("List Tests", () => {
12961296 </ List >
12971297 ) ;
12981298
1299- cy . get ( "[ui5-li-custom]" ) . click ( ) ;
1299+ cy . get ( "[ui5-li-custom]" ) . realClick ( ) ;
13001300 cy . get ( "[ui5-li-custom]" ) . should ( "be.focused" ) ;
13011301
13021302 // F7 goes to first focusable element
@@ -1329,7 +1329,7 @@ describe("List Tests", () => {
13291329 </ div >
13301330 ) ;
13311331
1332- cy . get ( "button" ) . click ( ) ;
1332+ cy . get ( "button" ) . realClick ( ) ;
13331333 cy . get ( "button" ) . should ( "be.focused" ) ;
13341334
13351335 // Tab into list item
@@ -1370,7 +1370,7 @@ describe("List Tests", () => {
13701370 ) ;
13711371
13721372 // Focus first list item
1373- cy . get ( "[ui5-li-custom]" ) . first ( ) . click ( ) ;
1373+ cy . get ( "[ui5-li-custom]" ) . first ( ) . realClick ( ) ;
13741374 cy . get ( "[ui5-li-custom]" ) . first ( ) . should ( "be.focused" ) ;
13751375
13761376 // F7 to enter (should go to first button)
@@ -1394,6 +1394,183 @@ describe("List Tests", () => {
13941394 cy . get ( "[ui5-button]" ) . eq ( 4 ) . should ( "be.focused" ) . and ( "contain" , "Item 2 - Second" ) ;
13951395 } ) ;
13961396
1397+ it ( "arrow down navigates to same-index element in next custom item" , ( ) => {
1398+ cy . mount (
1399+ < List >
1400+ < ListItemCustom >
1401+ < Button > Item 1 - First</ Button >
1402+ < Button > Item 1 - Second</ Button >
1403+ </ ListItemCustom >
1404+ < ListItemCustom >
1405+ < Button > Item 2 - First</ Button >
1406+ < Button > Item 2 - Second</ Button >
1407+ </ ListItemCustom >
1408+ < ListItemCustom >
1409+ < Button > Item 3 - First</ Button >
1410+ < Button > Item 3 - Second</ Button >
1411+ </ ListItemCustom >
1412+ </ List >
1413+ ) ;
1414+
1415+ // Focus first button in first item
1416+ cy . get ( "[ui5-button]" ) . first ( ) . realClick ( ) ;
1417+ cy . get ( "[ui5-button]" ) . first ( ) . should ( "be.focused" ) ;
1418+
1419+ // Arrow down should move to first button in second item
1420+ cy . realPress ( "ArrowDown" ) ;
1421+ cy . get ( "[ui5-button]" ) . eq ( 2 ) . should ( "be.focused" ) . and ( "contain" , "Item 2 - First" ) ;
1422+
1423+ // Arrow down again should move to first button in third item
1424+ cy . realPress ( "ArrowDown" ) ;
1425+ cy . get ( "[ui5-button]" ) . eq ( 4 ) . should ( "be.focused" ) . and ( "contain" , "Item 3 - First" ) ;
1426+ } ) ;
1427+
1428+ it ( "arrow up navigates to same-index element in previous custom item" , ( ) => {
1429+ cy . mount (
1430+ < List >
1431+ < ListItemCustom >
1432+ < Button > Item 1 - First</ Button >
1433+ < Button > Item 1 - Second</ Button >
1434+ </ ListItemCustom >
1435+ < ListItemCustom >
1436+ < Button > Item 2 - First</ Button >
1437+ < Button > Item 2 - Second</ Button >
1438+ </ ListItemCustom >
1439+ < ListItemCustom >
1440+ < Button > Item 3 - First</ Button >
1441+ < Button > Item 3 - Second</ Button >
1442+ </ ListItemCustom >
1443+ </ List >
1444+ ) ;
1445+
1446+ // Focus second button in last item
1447+ cy . get ( "[ui5-button]" ) . eq ( 5 ) . realClick ( ) ;
1448+ cy . get ( "[ui5-button]" ) . eq ( 5 ) . should ( "be.focused" ) ;
1449+
1450+ // Arrow up should move to second button in second item
1451+ cy . realPress ( "ArrowUp" ) ;
1452+ cy . get ( "[ui5-button]" ) . eq ( 3 ) . should ( "be.focused" ) . and ( "contain" , "Item 2 - Second" ) ;
1453+
1454+ // Arrow up again should move to second button in first item
1455+ cy . realPress ( "ArrowUp" ) ;
1456+ cy . get ( "[ui5-button]" ) . eq ( 1 ) . should ( "be.focused" ) . and ( "contain" , "Item 1 - Second" ) ;
1457+ } ) ;
1458+
1459+ it ( "arrow navigation skips standard list items" , ( ) => {
1460+ cy . mount (
1461+ < List >
1462+ < ListItemCustom >
1463+ < Button > Custom 1</ Button >
1464+ </ ListItemCustom >
1465+ < ListItemStandard > Standard Item</ ListItemStandard >
1466+ < ListItemStandard > Another Standard</ ListItemStandard >
1467+ < ListItemCustom >
1468+ < Button > Custom 2</ Button >
1469+ </ ListItemCustom >
1470+ </ List >
1471+ ) ;
1472+
1473+ // Focus button in first custom item
1474+ cy . get ( "[ui5-button]" ) . first ( ) . realClick ( ) ;
1475+ cy . get ( "[ui5-button]" ) . first ( ) . should ( "be.focused" ) ;
1476+
1477+ // Arrow down should skip standard items and focus button in second custom item
1478+ cy . realPress ( "ArrowDown" ) ;
1479+ cy . get ( "[ui5-button]" ) . last ( ) . should ( "be.focused" ) . and ( "contain" , "Custom 2" ) ;
1480+
1481+ // Arrow up should skip standard items and return to first custom item
1482+ cy . realPress ( "ArrowUp" ) ;
1483+ cy . get ( "[ui5-button]" ) . first ( ) . should ( "be.focused" ) . and ( "contain" , "Custom 1" ) ;
1484+ } ) ;
1485+
1486+ it ( "arrow navigation works across groups" , ( ) => {
1487+ cy . mount (
1488+ < List >
1489+ < ListItemCustom >
1490+ < Button > Before Group</ Button >
1491+ </ ListItemCustom >
1492+ < ListItemGroup headerText = "Group 1" >
1493+ < ListItemCustom >
1494+ < Button > In Group 1</ Button >
1495+ </ ListItemCustom >
1496+ </ ListItemGroup >
1497+ < ListItemGroup headerText = "Group 2" >
1498+ < ListItemCustom >
1499+ < Button > In Group 2</ Button >
1500+ </ ListItemCustom >
1501+ </ ListItemGroup >
1502+ < ListItemCustom >
1503+ < Button > After Group</ Button >
1504+ </ ListItemCustom >
1505+ </ List >
1506+ ) ;
1507+
1508+ // Focus button before groups
1509+ cy . get ( "[ui5-button]" ) . first ( ) . realClick ( ) ;
1510+
1511+ // Navigate down through groups
1512+ cy . realPress ( "ArrowDown" ) ;
1513+ cy . get ( "[ui5-button]" ) . eq ( 1 ) . should ( "be.focused" ) . and ( "contain" , "In Group 1" ) ;
1514+
1515+ cy . realPress ( "ArrowDown" ) ;
1516+ cy . get ( "[ui5-button]" ) . eq ( 2 ) . should ( "be.focused" ) . and ( "contain" , "In Group 2" ) ;
1517+
1518+ cy . realPress ( "ArrowDown" ) ;
1519+ cy . get ( "[ui5-button]" ) . last ( ) . should ( "be.focused" ) . and ( "contain" , "After Group" ) ;
1520+ } ) ;
1521+
1522+ it ( "arrow navigation handles items with different element counts" , ( ) => {
1523+ cy . mount (
1524+ < List >
1525+ < ListItemCustom >
1526+ < Button > Item 1 - A</ Button >
1527+ < Button > Item 1 - B</ Button >
1528+ < Button > Item 1 - C</ Button >
1529+ < Button > Item 1 - D</ Button >
1530+ </ ListItemCustom >
1531+ < ListItemCustom >
1532+ < Button > Item 2 - A</ Button >
1533+ < Button > Item 2 - B</ Button >
1534+ </ ListItemCustom >
1535+ </ List >
1536+ ) ;
1537+
1538+ // Focus fourth button (index 3) in first item
1539+ cy . get ( "[ui5-button]" ) . eq ( 3 ) . realClick ( ) ;
1540+ cy . get ( "[ui5-button]" ) . eq ( 3 ) . should ( "be.focused" ) ;
1541+
1542+ // Arrow down should focus last button in second item (index clamped to 1)
1543+ cy . realPress ( "ArrowDown" ) ;
1544+ cy . get ( "[ui5-button]" ) . eq ( 5 ) . should ( "be.focused" ) . and ( "contain" , "Item 2 - B" ) ;
1545+ } ) ;
1546+
1547+ it ( "arrow navigation does nothing at list boundaries" , ( ) => {
1548+ cy . mount (
1549+ < List >
1550+ < ListItemCustom >
1551+ < Button > First Item</ Button >
1552+ </ ListItemCustom >
1553+ < ListItemCustom >
1554+ < Button > Last Item</ Button >
1555+ </ ListItemCustom >
1556+ </ List >
1557+ ) ;
1558+
1559+ // Focus first button
1560+ cy . get ( "[ui5-button]" ) . first ( ) . realClick ( ) ;
1561+
1562+ // Arrow up should do nothing (at top boundary)
1563+ cy . realPress ( "ArrowUp" ) ;
1564+ cy . get ( "[ui5-button]" ) . first ( ) . should ( "be.focused" ) ;
1565+
1566+ // Focus last button
1567+ cy . get ( "[ui5-button]" ) . last ( ) . realClick ( ) ;
1568+
1569+ // Arrow down should do nothing (at bottom boundary)
1570+ cy . realPress ( "ArrowDown" ) ;
1571+ cy . get ( "[ui5-button]" ) . last ( ) . should ( "be.focused" ) ;
1572+ } ) ;
1573+
13971574 it ( "keyboard handling on TAB when 2 level nested UI5Element is focused" , ( ) => {
13981575 cy . mount (
13991576 < div >
0 commit comments