@@ -1280,6 +1280,264 @@ describe('FocusScope', function () {
1280
1280
} ) ;
1281
1281
} ) ;
1282
1282
1283
+ it ( 'skips radio buttons that are in the same group and are not the selectable one forwards' , async function ( ) {
1284
+ function Test ( ) {
1285
+ return (
1286
+ < FocusScope contain >
1287
+ < button data-testid = "button1" > button</ button >
1288
+ < form >
1289
+ < fieldset >
1290
+ < legend > Select a maintenance drone:</ legend >
1291
+
1292
+ < div >
1293
+ < input type = "radio" id = "huey" name = "drone" value = "huey" defaultChecked />
1294
+ < label htmlFor = "huey" > Huey</ label >
1295
+ </ div >
1296
+
1297
+ < div >
1298
+ < input type = "radio" id = "dewey" name = "drone" value = "dewey" />
1299
+ < label htmlFor = "dewey" > Dewey</ label >
1300
+ </ div >
1301
+ < button data-testid = "button2" > button</ button >
1302
+ < div >
1303
+ < input type = "radio" id = "louie" name = "drone" value = "louie" />
1304
+ < label htmlFor = "louie" > Louie</ label >
1305
+ </ div >
1306
+ </ fieldset >
1307
+ < fieldset >
1308
+ < legend > Select a ship:</ legend >
1309
+
1310
+ < div >
1311
+ < input type = "radio" id = "larry" name = "ship" value = "larry" />
1312
+ < label htmlFor = "larry" > Larry</ label >
1313
+ </ div >
1314
+
1315
+ < div >
1316
+ < input type = "radio" id = "moe" name = "ship" value = "moe" />
1317
+ < label htmlFor = "moe" > Moe</ label >
1318
+ </ div >
1319
+ < button data-testid = "button3" > button</ button >
1320
+ < div >
1321
+ < input type = "radio" id = "curly" name = "ship" value = "curly" />
1322
+ < label htmlFor = "curly" > Curly</ label >
1323
+ </ div >
1324
+ </ fieldset >
1325
+ </ form >
1326
+ < button data-testid = "button4" > button</ button >
1327
+ </ FocusScope >
1328
+ ) ;
1329
+ }
1330
+
1331
+ let { getByTestId, getAllByRole} = render ( < Test /> ) ;
1332
+ let radios = getAllByRole ( 'radio' ) ;
1333
+ await user . tab ( ) ;
1334
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button1' ) ) ;
1335
+ await user . tab ( ) ;
1336
+ expect ( document . activeElement ) . toBe ( radios [ 0 ] ) ;
1337
+ await user . tab ( ) ;
1338
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button2' ) ) ;
1339
+ await user . tab ( ) ;
1340
+ expect ( document . activeElement ) . toBe ( radios [ 3 ] ) ;
1341
+ await user . tab ( ) ;
1342
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button3' ) ) ;
1343
+ await user . tab ( ) ;
1344
+ expect ( document . activeElement ) . toBe ( radios [ 5 ] ) ;
1345
+ await user . tab ( ) ;
1346
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button4' ) ) ;
1347
+ } ) ;
1348
+
1349
+ it ( 'skips radio buttons that are in the same group and are not the selectable one forwards outside of a form' , async function ( ) {
1350
+ function Test ( ) {
1351
+ return (
1352
+ < FocusScope contain >
1353
+ < button data-testid = "button1" > button</ button >
1354
+ < fieldset >
1355
+ < legend > Select a maintenance drone:</ legend >
1356
+
1357
+ < div >
1358
+ < input type = "radio" id = "huey" name = "drone" value = "huey" defaultChecked />
1359
+ < label htmlFor = "huey" > Huey</ label >
1360
+ </ div >
1361
+
1362
+ < div >
1363
+ < input type = "radio" id = "dewey" name = "drone" value = "dewey" />
1364
+ < label htmlFor = "dewey" > Dewey</ label >
1365
+ </ div >
1366
+ < button data-testid = "button2" > button</ button >
1367
+ < div >
1368
+ < input type = "radio" id = "louie" name = "drone" value = "louie" />
1369
+ < label htmlFor = "louie" > Louie</ label >
1370
+ </ div >
1371
+ </ fieldset >
1372
+ < fieldset >
1373
+ < legend > Select a ship:</ legend >
1374
+
1375
+ < div >
1376
+ < input type = "radio" id = "larry" name = "ship" value = "larry" />
1377
+ < label htmlFor = "larry" > Larry</ label >
1378
+ </ div >
1379
+
1380
+ < div >
1381
+ < input type = "radio" id = "moe" name = "ship" value = "moe" />
1382
+ < label htmlFor = "moe" > Moe</ label >
1383
+ </ div >
1384
+ < button data-testid = "button3" > button</ button >
1385
+ < div >
1386
+ < input type = "radio" id = "curly" name = "ship" value = "curly" />
1387
+ < label htmlFor = "curly" > Curly</ label >
1388
+ </ div >
1389
+ </ fieldset >
1390
+ < button data-testid = "button4" > button</ button >
1391
+ </ FocusScope >
1392
+ ) ;
1393
+ }
1394
+
1395
+ let { getByTestId, getAllByRole} = render ( < Test /> ) ;
1396
+ let radios = getAllByRole ( 'radio' ) ;
1397
+ await user . tab ( ) ;
1398
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button1' ) ) ;
1399
+ await user . tab ( ) ;
1400
+ expect ( document . activeElement ) . toBe ( radios [ 0 ] ) ;
1401
+ await user . tab ( ) ;
1402
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button2' ) ) ;
1403
+ await user . tab ( ) ;
1404
+ expect ( document . activeElement ) . toBe ( radios [ 3 ] ) ;
1405
+ await user . tab ( ) ;
1406
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button3' ) ) ;
1407
+ await user . tab ( ) ;
1408
+ expect ( document . activeElement ) . toBe ( radios [ 5 ] ) ;
1409
+ await user . tab ( ) ;
1410
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button4' ) ) ;
1411
+ } ) ;
1412
+
1413
+ it ( 'skips radio buttons that are in the same group and are not the selectable one backwards' , async function ( ) {
1414
+ function Test ( ) {
1415
+ return (
1416
+ < FocusScope contain >
1417
+ < button data-testid = "button1" > button</ button >
1418
+ < form >
1419
+ < fieldset >
1420
+ < legend > Select a maintenance drone:</ legend >
1421
+
1422
+ < div >
1423
+ < input type = "radio" id = "huey" name = "drone" value = "huey" defaultChecked />
1424
+ < label htmlFor = "huey" > Huey</ label >
1425
+ </ div >
1426
+
1427
+ < div >
1428
+ < input type = "radio" id = "dewey" name = "drone" value = "dewey" />
1429
+ < label htmlFor = "dewey" > Dewey</ label >
1430
+ </ div >
1431
+ < button data-testid = "button2" > button</ button >
1432
+ < div >
1433
+ < input type = "radio" id = "louie" name = "drone" value = "louie" />
1434
+ < label htmlFor = "louie" > Louie</ label >
1435
+ </ div >
1436
+ </ fieldset >
1437
+ < fieldset >
1438
+ < legend > Select a ship:</ legend >
1439
+
1440
+ < div >
1441
+ < input type = "radio" id = "larry" name = "ship" value = "larry" />
1442
+ < label htmlFor = "larry" > Larry</ label >
1443
+ </ div >
1444
+
1445
+ < div >
1446
+ < input type = "radio" id = "moe" name = "ship" value = "moe" />
1447
+ < label htmlFor = "moe" > Moe</ label >
1448
+ </ div >
1449
+ < button data-testid = "button3" > button</ button >
1450
+ < div >
1451
+ < input type = "radio" id = "curly" name = "ship" value = "curly" />
1452
+ < label htmlFor = "curly" > Curly</ label >
1453
+ </ div >
1454
+ </ fieldset >
1455
+ </ form >
1456
+ < button data-testid = "button4" > button</ button >
1457
+ </ FocusScope >
1458
+ ) ;
1459
+ }
1460
+
1461
+ let { getByTestId, getAllByRole} = render ( < Test /> ) ;
1462
+ let radios = getAllByRole ( 'radio' ) ;
1463
+ await user . click ( getByTestId ( 'button4' ) ) ;
1464
+ await user . tab ( { shift : true } ) ;
1465
+ expect ( document . activeElement ) . toBe ( radios [ 5 ] ) ;
1466
+ await user . tab ( { shift : true } ) ;
1467
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button3' ) ) ;
1468
+ await user . tab ( { shift : true } ) ;
1469
+ expect ( document . activeElement ) . toBe ( radios [ 4 ] ) ;
1470
+ await user . tab ( { shift : true } ) ;
1471
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button2' ) ) ;
1472
+ await user . tab ( { shift : true } ) ;
1473
+ expect ( document . activeElement ) . toBe ( radios [ 0 ] ) ;
1474
+ await user . tab ( { shift : true } ) ;
1475
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button1' ) ) ;
1476
+ } ) ;
1477
+
1478
+ it ( 'skips radio buttons that are in the same group and are not the selectable one backwards outside of a form' , async function ( ) {
1479
+ function Test ( ) {
1480
+ return (
1481
+ < FocusScope contain >
1482
+ < button data-testid = "button1" > button</ button >
1483
+ < fieldset >
1484
+ < legend > Select a maintenance drone:</ legend >
1485
+
1486
+ < div >
1487
+ < input type = "radio" id = "huey" name = "drone" value = "huey" defaultChecked />
1488
+ < label htmlFor = "huey" > Huey</ label >
1489
+ </ div >
1490
+
1491
+ < div >
1492
+ < input type = "radio" id = "dewey" name = "drone" value = "dewey" />
1493
+ < label htmlFor = "dewey" > Dewey</ label >
1494
+ </ div >
1495
+ < button data-testid = "button2" > button</ button >
1496
+ < div >
1497
+ < input type = "radio" id = "louie" name = "drone" value = "louie" />
1498
+ < label htmlFor = "louie" > Louie</ label >
1499
+ </ div >
1500
+ </ fieldset >
1501
+ < fieldset >
1502
+ < legend > Select a ship:</ legend >
1503
+
1504
+ < div >
1505
+ < input type = "radio" id = "larry" name = "ship" value = "larry" />
1506
+ < label htmlFor = "larry" > Larry</ label >
1507
+ </ div >
1508
+
1509
+ < div >
1510
+ < input type = "radio" id = "moe" name = "ship" value = "moe" />
1511
+ < label htmlFor = "moe" > Moe</ label >
1512
+ </ div >
1513
+ < button data-testid = "button3" > button</ button >
1514
+ < div >
1515
+ < input type = "radio" id = "curly" name = "ship" value = "curly" />
1516
+ < label htmlFor = "curly" > Curly</ label >
1517
+ </ div >
1518
+ </ fieldset >
1519
+ < button data-testid = "button4" > button</ button >
1520
+ </ FocusScope >
1521
+ ) ;
1522
+ }
1523
+
1524
+ let { getByTestId, getAllByRole} = render ( < Test /> ) ;
1525
+ let radios = getAllByRole ( 'radio' ) ;
1526
+ await user . click ( getByTestId ( 'button4' ) ) ;
1527
+ await user . tab ( { shift : true } ) ;
1528
+ expect ( document . activeElement ) . toBe ( radios [ 5 ] ) ;
1529
+ await user . tab ( { shift : true } ) ;
1530
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button3' ) ) ;
1531
+ await user . tab ( { shift : true } ) ;
1532
+ expect ( document . activeElement ) . toBe ( radios [ 4 ] ) ;
1533
+ await user . tab ( { shift : true } ) ;
1534
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button2' ) ) ;
1535
+ await user . tab ( { shift : true } ) ;
1536
+ expect ( document . activeElement ) . toBe ( radios [ 0 ] ) ;
1537
+ await user . tab ( { shift : true } ) ;
1538
+ expect ( document . activeElement ) . toBe ( getByTestId ( 'button1' ) ) ;
1539
+ } ) ;
1540
+
1283
1541
describe ( 'nested focus scopes' , function ( ) {
1284
1542
it ( 'should make child FocusScopes the active scope regardless of DOM structure' , function ( ) {
1285
1543
function ChildComponent ( props ) {
0 commit comments