saket / cascade

Nested popup menus with smooth height animations for Android

Home Page:https://saket.github.io/cascade

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Interested in adding a centered animated popup menu?

MV-GH opened this issue · comments

I made centered popup menu variation of of the CascadeDropdownMenu. Are you interested in having this added to this library?

cot8LTIDkF.mp4
Source Code
@Composable
fun CascadeCenteredDropdownMenu(
    expanded: Boolean,
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    fixedWidth: Dp = LocalConfiguration.current.screenWidthDp.dp * POPUP_MENU_WIDTH_RATIO,
    shadowElevation: Dp = 3.dp,
    properties: PopupProperties = PopupProperties(focusable = true),
    state: CascadeState = rememberCascadeState(),
    content: @Composable CascadeColumnScope.() -> Unit,
) {
    val expandedStates = remember { MutableTransitionState(false) }
    expandedStates.targetState = expanded

    if (expandedStates.currentState || expandedStates.targetState) {
        val transformOriginState = remember { mutableStateOf(TransformOrigin.Center) }

        // A full sized popup is shown so that content can render fake shadows
        // that do not suffer from https://issuetracker.google.com/issues/236109671.

        Popup(
            alignment = Alignment.Center,
            onDismissRequest = onDismissRequest,
            properties = properties.copy(usePlatformDefaultWidth = false),
        ) {
            Box(
                Modifier
                    .fillMaxSize()
                    .then(properties.dismissOnClickOutside) {
                        clickableWithoutRipple(onClick = onDismissRequest)
                    },
                Alignment.Center,
            ) {
                PopupContent(
                    modifier = Modifier
                        // Prevent clicks from leaking behind. Otherwise, they'll get picked up as outside
                        // clicks to dismiss the popup. This must be set _before_ the downstream modifiers to
                        // avoid overriding any clickable modifiers registered by the developer.
                        .clickableWithoutRipple {}
                        .padding(vertical = LARGE_PADDING)
                        .then(modifier),
                    state = state,
                    fixedWidth = fixedWidth,
                    expandedStates = expandedStates,
                    transformOriginState = transformOriginState,
                    shadowElevation = shadowElevation,
                    tonalElevation = 3.dp,
                    content = content,
                )
            }
        }
    }
}

If not, could you allow making PopupContent not internal so I can depend on the upstream?

@saket

Thanks for asking! I don't think I want to offer two variants for keeping the library simple.

If not, could you allow making PopupContent not internal so I can depend on the upstream?

You still can!

@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")

import me.saket.cascade.PopupContent as CascadePopupContent

That workaround may not work for long. K2 compiler gives warnings for it

w: file://app/src/main/java/com/jerboa/util/cascade/CustomCascadeDropdown.kt:3:36 This code uses error suppression for 'INVISIBLE_REFERENCE'. While it might compile and work, the compiler behavior is UNSPECIFIED and WON'T BE PRESERVED. Please report your use case to the Kotlin issue tracker instead: https://kotl.in/issue