@@ -6,6 +6,7 @@ import androidx.compose.foundation.gestures.detectTapGestures
6
6
import androidx.compose.foundation.layout.fillMaxSize
7
7
import androidx.compose.foundation.shape.RoundedCornerShape
8
8
import androidx.compose.runtime.Composable
9
+ import androidx.compose.runtime.LaunchedEffect
9
10
import androidx.compose.runtime.getValue
10
11
import androidx.compose.runtime.mutableStateOf
11
12
import androidx.compose.runtime.remember
@@ -18,6 +19,7 @@ import androidx.compose.ui.graphics.Brush
18
19
import androidx.compose.ui.graphics.Color
19
20
import androidx.compose.ui.graphics.Shape
20
21
import androidx.compose.ui.input.pointer.pointerInput
22
+ import androidx.compose.ui.platform.LocalView
21
23
import androidx.compose.ui.platform.testTag
22
24
import androidx.compose.ui.unit.Dp
23
25
import androidx.compose.ui.unit.IntOffset
@@ -34,6 +36,7 @@ import com.microsoft.fluentui.compose.SwipeableState
34
36
import com.microsoft.fluentui.theme.FluentTheme
35
37
import com.microsoft.fluentui.theme.token.ControlTokens
36
38
import com.microsoft.fluentui.theme.token.controlTokens.BehaviorType
39
+ import com.microsoft.fluentui.theme.token.controlTokens.DrawerAccessibilityAnnouncement
37
40
import com.microsoft.fluentui.theme.token.controlTokens.DrawerInfo
38
41
import com.microsoft.fluentui.theme.token.controlTokens.DrawerTokens
39
42
import kotlinx.coroutines.CancellationException
@@ -323,6 +326,23 @@ internal fun Scrim(
323
326
}
324
327
}
325
328
329
+ @Composable
330
+ internal fun AnnounceDrawerActions (drawerState : DrawerState , talkbackAnnouncement : DrawerAccessibilityAnnouncement ){ // Announces actions for drawer through Talkback
331
+ val view = LocalView .current
332
+ var previousState by remember { mutableStateOf(drawerState.enable) }
333
+
334
+ LaunchedEffect (drawerState.enable) {
335
+ if (drawerState.enable != previousState) {
336
+ if (drawerState.enable) {
337
+ view.announceForAccessibility(talkbackAnnouncement.opened)
338
+ } else {
339
+ view.announceForAccessibility(talkbackAnnouncement.closed)
340
+ }
341
+ previousState = drawerState.enable
342
+ }
343
+ }
344
+
345
+ }
326
346
/* *
327
347
*
328
348
* Drawer block interaction with the rest of an app’s content with a scrim.
@@ -348,25 +368,27 @@ fun Drawer(
348
368
drawerState : DrawerState = rememberDrawerState(),
349
369
scrimVisible : Boolean = true,
350
370
offset : IntOffset ? = null,
371
+ talkbackAnnouncement : DrawerAccessibilityAnnouncement = DrawerAccessibilityAnnouncement (),
351
372
drawerTokens : DrawerTokens ? = null,
352
373
drawerContent : @Composable () -> Unit ,
353
374
preventDismissalOnScrimClick : Boolean = false,
354
375
onScrimClick : () -> Unit = {}
355
376
) {
377
+ val tokens = drawerTokens
378
+ ? : FluentTheme .controlTokens.tokens[ControlTokens .ControlType .DrawerControlType ] as DrawerTokens
379
+ val drawerInfo = DrawerInfo (type = behaviorType)
380
+ AnnounceDrawerActions (drawerState, talkbackAnnouncement = talkbackAnnouncement)
381
+
356
382
if (drawerState.enable) {
357
383
val themeID =
358
384
FluentTheme .themeID // Adding This only for recomposition in case of Token Updates. Unused otherwise.
359
- val tokens = drawerTokens
360
- ? : FluentTheme .controlTokens.tokens[ControlTokens .ControlType .DrawerControlType ] as DrawerTokens
361
-
362
385
val popupPositionProvider = DrawerPositionProvider (offset)
363
386
val scope = rememberCoroutineScope()
364
387
val close: () -> Unit = {
365
388
if (drawerState.confirmStateChange(DrawerValue .Closed )) {
366
389
scope.launch { drawerState.close() }
367
390
}
368
391
}
369
- val drawerInfo = DrawerInfo (type = behaviorType)
370
392
Popup (
371
393
onDismissRequest = close,
372
394
popupPositionProvider = popupPositionProvider,
@@ -478,27 +500,28 @@ fun BottomDrawer(
478
500
showHandle : Boolean = true,
479
501
enableSwipeDismiss : Boolean = true,
480
502
windowInsetsType : Int = WindowInsetsCompat .Type .systemBars(),
503
+ talkbackAnnouncement : DrawerAccessibilityAnnouncement = DrawerAccessibilityAnnouncement (),
481
504
drawerTokens : DrawerTokens ? = null,
482
505
drawerContent : @Composable () -> Unit ,
483
506
maxLandscapeWidthFraction : Float = 1F,
484
507
preventDismissalOnScrimClick : Boolean = false,
485
508
onScrimClick : () -> Unit = {},
486
509
) {
487
-
510
+ val behaviorType =
511
+ if (slideOver) BehaviorType .BOTTOM_SLIDE_OVER else BehaviorType .BOTTOM
512
+ val drawerInfo = DrawerInfo (type = behaviorType)
513
+ val tokens = drawerTokens
514
+ ? : FluentTheme .controlTokens.tokens[ControlTokens .ControlType .DrawerControlType ] as DrawerTokens
515
+ AnnounceDrawerActions (drawerState, talkbackAnnouncement = talkbackAnnouncement)
488
516
if (drawerState.enable) {
489
517
val themeID =
490
518
FluentTheme .themeID // Adding This only for recomposition in case of Token Updates. Unused otherwise.
491
- val tokens = drawerTokens
492
- ? : FluentTheme .controlTokens.tokens[ControlTokens .ControlType .DrawerControlType ] as DrawerTokens
493
519
val scope = rememberCoroutineScope()
494
520
val close: () -> Unit = {
495
521
if (drawerState.confirmStateChange(DrawerValue .Closed )) {
496
522
scope.launch { drawerState.close() }
497
523
}
498
524
}
499
- val behaviorType =
500
- if (slideOver) BehaviorType .BOTTOM_SLIDE_OVER else BehaviorType .BOTTOM
501
- val drawerInfo = DrawerInfo (type = behaviorType)
502
525
BackHandler { // TODO: Add pull down animation with predictive back
503
526
close()
504
527
}
0 commit comments