@@ -1164,4 +1164,96 @@ describe('Preview', () => {
11641164 expect ( baseElement . querySelector ( '.rc-image-preview' ) ) . toHaveClass ( customClassnames . popup . root ) ;
11651165 expect ( baseElement . querySelector ( '.rc-image-preview' ) ) . toHaveStyle ( customStyles . popup . root ) ;
11661166 } ) ;
1167+
1168+ it ( 'Image wrapper should be keyboard focusable when preview enabled' , ( ) => {
1169+ const { container } = render ( < Image src = "src" alt = "keyboard test" /> ) ;
1170+
1171+ const wrapper = container . querySelector ( '.rc-image' ) as HTMLElement ;
1172+ expect ( wrapper ) . toHaveAttribute ( 'role' , 'button' ) ;
1173+ expect ( wrapper ) . toHaveAttribute ( 'tabindex' , '0' ) ;
1174+ } ) ;
1175+
1176+ it ( 'Pressing Enter on image wrapper should open preview' , ( ) => {
1177+ const { container } = render ( < Image src = "src" alt = "keyboard open" /> ) ;
1178+
1179+ const wrapper = container . querySelector ( '.rc-image' ) as HTMLElement ;
1180+ wrapper . focus ( ) ;
1181+ fireEvent . keyDown ( wrapper , { key : 'Enter' } ) ;
1182+
1183+ act ( ( ) => {
1184+ jest . runAllTimers ( ) ;
1185+ } ) ;
1186+
1187+ expect ( document . querySelector ( '.rc-image-preview' ) ) . toBeTruthy ( ) ;
1188+ } ) ;
1189+
1190+ it ( 'Pressing Space on image wrapper should open preview' , ( ) => {
1191+ const { container } = render ( < Image src = "src" alt = "keyboard open space" /> ) ;
1192+
1193+ const wrapper = container . querySelector ( '.rc-image' ) as HTMLElement ;
1194+ wrapper . focus ( ) ;
1195+ fireEvent . keyDown ( wrapper , { key : ' ' } ) ;
1196+
1197+ act ( ( ) => {
1198+ jest . runAllTimers ( ) ;
1199+ } ) ;
1200+
1201+ expect ( document . querySelector ( '.rc-image-preview' ) ) . toBeTruthy ( ) ;
1202+ } ) ;
1203+
1204+ it ( 'Preview dialog should have role dialog and receive focus' , ( ) => {
1205+ render ( < Image src = "src" alt = "dialog a11y" preview = { { open : true } } /> ) ;
1206+
1207+ const preview = document . querySelector ( '.rc-image-preview' ) as HTMLElement ;
1208+ expect ( preview ) . toHaveAttribute ( 'role' , 'dialog' ) ;
1209+ expect ( preview ) . toHaveAttribute ( 'aria-modal' , 'true' ) ;
1210+ expect ( preview ) . toHaveAttribute ( 'aria-label' , 'dialog a11y' ) ;
1211+ } ) ;
1212+
1213+ it ( 'Preview wrapper should be focusable after portal renders' , ( ) => {
1214+ const rectSpy = jest . spyOn ( HTMLElement . prototype , 'getBoundingClientRect' ) . mockReturnValue ( {
1215+ x : 0 ,
1216+ y : 0 ,
1217+ width : 100 ,
1218+ height : 100 ,
1219+ top : 0 ,
1220+ right : 100 ,
1221+ bottom : 100 ,
1222+ left : 0 ,
1223+ toJSON : ( ) => undefined ,
1224+ } as DOMRect ) ;
1225+
1226+ render ( < Image src = "src" alt = "focus portal" preview = { { open : true } } /> ) ;
1227+
1228+ act ( ( ) => {
1229+ jest . runAllTimers ( ) ;
1230+ } ) ;
1231+
1232+ const preview = document . querySelector ( '.rc-image-preview' ) as HTMLElement ;
1233+
1234+ expect ( preview . contains ( document . activeElement ) ) . toBeTruthy ( ) ;
1235+
1236+ rectSpy . mockRestore ( ) ;
1237+ } ) ;
1238+
1239+ it ( 'Preview open should render focusable wrapper' , ( ) => {
1240+ render ( < Image src = "src" alt = "focus test" preview = { { open : true } } /> ) ;
1241+
1242+ const preview = document . querySelector ( '.rc-image-preview' ) as HTMLElement ;
1243+ expect ( preview ) . toHaveAttribute ( 'tabindex' , '-1' ) ;
1244+ } ) ;
1245+
1246+ it ( 'Pressing Enter should not open preview when preview is disabled' , ( ) => {
1247+ const { container } = render ( < Image src = "src" alt = "disabled preview" preview = { false } /> ) ;
1248+
1249+ const wrapper = container . querySelector ( '.rc-image' ) as HTMLElement ;
1250+ wrapper . focus ( ) ;
1251+ fireEvent . keyDown ( wrapper , { key : 'Enter' } ) ;
1252+
1253+ act ( ( ) => {
1254+ jest . runAllTimers ( ) ;
1255+ } ) ;
1256+
1257+ expect ( document . querySelector ( '.rc-image-preview' ) ) . toBeFalsy ( ) ;
1258+ } ) ;
11671259} ) ;
0 commit comments