diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:35:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:35:29 +0000 |
commit | 59203c63bb777a3bacec32fb8830fba33540e809 (patch) | |
tree | 58298e711c0ff0575818c30485b44a2f21bf28a0 /mobile/android/android-components/components/compose | |
parent | Adding upstream version 126.0.1. (diff) | |
download | firefox-59203c63bb777a3bacec32fb8830fba33540e809.tar.xz firefox-59203c63bb777a3bacec32fb8830fba33540e809.zip |
Adding upstream version 127.0.upstream/127.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mobile/android/android-components/components/compose')
-rw-r--r-- | mobile/android/android-components/components/compose/cfr/src/main/java/mozilla/components/compose/cfr/CFRPopupLayout.kt | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/mobile/android/android-components/components/compose/cfr/src/main/java/mozilla/components/compose/cfr/CFRPopupLayout.kt b/mobile/android/android-components/components/compose/cfr/src/main/java/mozilla/components/compose/cfr/CFRPopupLayout.kt new file mode 100644 index 0000000000..4585c0303d --- /dev/null +++ b/mobile/android/android-components/components/compose/cfr/src/main/java/mozilla/components/compose/cfr/CFRPopupLayout.kt @@ -0,0 +1,160 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package mozilla.components.compose.cfr + +import android.view.View +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.material.Button +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView + +typealias DismissAction = () -> Unit + +/** + * A layout for displaying a [CFRPopup] anchored by [anchorContent]. + * + * @param showCFR Whether to display the CFR. + * @param properties [CFRPopupProperties] allowing to customize the popup appearance and behavior. + * @param onCFRShown Invoked when the CFR is displayed. + * @param onDismiss Invoked when the CFR is dismissed. Returns true if the dismissal was + * explicit (e.g. clicked via the "X" button). + * @param text [Text] block containing the CFR's message. + * @param action Optional Composable displayed below [text]. Provides a [DismissAction] if the CFR needs + * to be dismissed after the action is invoked. + * @param anchorContent The Composable to anchor the CFR to. + */ +@Composable +fun CFRPopupLayout( + showCFR: Boolean, + properties: CFRPopupProperties, + onCFRShown: () -> Unit, + onDismiss: (Boolean) -> Unit, + text: @Composable () -> Unit, + action: @Composable (dismissCFR: DismissAction) -> Unit = {}, + anchorContent: @Composable () -> Unit, +) { + var hasDismissedCFR by rememberSaveable { mutableStateOf(false) } + + Box( + modifier = Modifier.height(intrinsicSize = IntrinsicSize.Min), + ) { + if (showCFR && !hasDismissedCFR) { + LaunchedEffect(Unit) { + onCFRShown() + } + + var popup: CFRPopup? = null + + val invokeDismiss: DismissAction = { + if (!hasDismissedCFR) { + popup?.dismiss() + } + popup = null + } + + AndroidView( + modifier = Modifier.fillMaxSize(), + factory = { context -> + View(context).also { + popup = CFRPopup( + anchor = it, + properties = properties, + onDismiss = { dismissFromButton -> + onDismiss(dismissFromButton) + hasDismissedCFR = true + }, + text = text, + action = { + action(invokeDismiss) + }, + ) + } + }, + onRelease = { + invokeDismiss() + }, + update = { + popup?.dismiss() + popup?.show() + }, + ) + } + + anchorContent() + } +} + +/** + * This is to validate the sizing of the underlying AndroidView. The current implementation of CFRs + * via [CFRPopupFullscreenLayout] do not render in previews. + */ +@Preview +@Composable +private fun CFRPopupLayoutPreview() { + var cfrVisible by remember { mutableStateOf(true) } + + Column( + modifier = Modifier + .fillMaxSize() + .background(color = Color.LightGray), + ) { + CFRPopupLayout( + showCFR = cfrVisible, + properties = CFRPopupProperties(), + onCFRShown = {}, + onDismiss = { cfrVisible = false }, + text = { + Text(text = "This is a CFR in Compose") + }, + action = { + TextButton(onClick = { cfrVisible = false }) { + Text(text = "Dismiss") + } + }, + ) { + Box(modifier = Modifier.size(300.dp)) { + Text( + text = "This is the thing the CFR is anchored to", + modifier = Modifier.align(alignment = Alignment.Center), + ) + } + } + + Spacer(modifier = Modifier.height(60.dp)) + + Box(modifier = Modifier.size(100.dp)) { + Text( + text = "This is just another element", + modifier = Modifier.align(alignment = Alignment.Center), + ) + } + + Spacer(modifier = Modifier.height(60.dp)) + + Button(onClick = { cfrVisible = true }) { + Text(text = "Show CFR") + } + } +} |