Skip to content

Commit

Permalink
Expect androidx.compose.material.DropdownMenu in common (#738)
Browse files Browse the repository at this point in the history
* Expect DropdownMenu in common

* Deprecate old DropdownMenu overloads

* Fix class name in tests

* Fix binary compatibility for DropdownMenuItem

* Move missing Rtl fix to common

* Revert DropdownMenuPositionProvider fixes

* Update Rtl test

* Fix DesktopMenuTest tests
  • Loading branch information
MatkovIvan committed Aug 10, 2023
1 parent 0bb1c8e commit 8f1df5e
Show file tree
Hide file tree
Showing 6 changed files with 400 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,13 @@ fun DropdownMenu(
* @param content the content of this dropdown menu, typically a [DropdownMenuItem]
*/
@Composable
fun DropdownMenu(
actual fun DropdownMenu(
expanded: Boolean,
onDismissRequest: () -> Unit,
modifier: Modifier = Modifier,
offset: DpOffset = DpOffset(0.dp, 0.dp),
scrollState: ScrollState = rememberScrollState(),
properties: PopupProperties = PopupProperties(focusable = true),
modifier: Modifier,
offset: DpOffset,
scrollState: ScrollState,
properties: PopupProperties,
content: @Composable ColumnScope.() -> Unit
) {
val expandedStates = remember { MutableTransitionState(false) }
Expand Down Expand Up @@ -200,12 +200,12 @@ fun DropdownMenu(
* appearance / behavior of this DropdownMenuItem in different [Interaction]s.
*/
@Composable
fun DropdownMenuItem(
actual fun DropdownMenuItem(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
modifier: Modifier,
enabled: Boolean,
contentPadding: PaddingValues,
interactionSource: MutableInteractionSource,
content: @Composable RowScope.() -> Unit
) {
DropdownMenuItemContent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.Interaction
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
Expand All @@ -34,6 +35,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
Expand All @@ -53,10 +55,95 @@ import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupPositionProvider
import androidx.compose.ui.window.PopupProperties
import kotlin.math.max
import kotlin.math.min


/**
* <a href="https://material.io/components/menus#dropdown-menu" class="external" target="_blank">Material Design dropdown menu</a>.
*
* A dropdown menu is a compact way of displaying multiple choices. It appears upon interaction with
* an element (such as an icon or button) or when users perform a specific action.
*
* ![Menus image](https://developer.android.com/images/reference/androidx/compose/material/menus.png)
*
* A [DropdownMenu] behaves similarly to a [Popup], and will use the position of the parent layout
* to position itself on screen. Commonly a [DropdownMenu] will be placed in a [Box] with a sibling
* that will be used as the 'anchor'. Note that a [DropdownMenu] by itself will not take up any
* space in a layout, as the menu is displayed in a separate window, on top of other content.
*
* The [content] of a [DropdownMenu] will typically be [DropdownMenuItem]s, as well as custom
* content. Using [DropdownMenuItem]s will result in a menu that matches the Material
* specification for menus. Also note that the [content] is placed inside a scrollable [Column],
* so using a [LazyColumn] as the root layout inside [content] is unsupported.
*
* [onDismissRequest] will be called when the menu should close - for example when there is a
* tap outside the menu, or when the back key is pressed.
*
* [DropdownMenu] changes its positioning depending on the available space, always trying to be
* fully visible. It will try to expand horizontally, depending on layout direction, to the end of
* its parent, then to the start of its parent, and then screen end-aligned. Vertically, it will
* try to expand to the bottom of its parent, then from the top of its parent, and then screen
* top-aligned. An [offset] can be provided to adjust the positioning of the menu for cases when
* the layout bounds of its parent do not coincide with its visual bounds. Note the offset will
* be applied in the direction in which the menu will decide to expand.
*
* Example usage:
* @sample androidx.compose.material.samples.MenuSample
*
* Example usage with a [ScrollState] to control the menu items scroll position:
* @sample androidx.compose.material.samples.MenuWithScrollStateSample
*
* @param expanded whether the menu is expanded or not
* @param onDismissRequest called when the user requests to dismiss the menu, such as by tapping
* outside the menu's bounds
* @param modifier [Modifier] to be applied to the menu's content
* @param offset [DpOffset] to be added to the position of the menu
* @param scrollState a [ScrollState] to used by the menu's content for items vertical scrolling
* @param properties [PopupProperties] for further customization of this popup's behavior
* @param content the content of this dropdown menu, typically a [DropdownMenuItem]
*/
@Composable
expect fun DropdownMenu(
expanded: Boolean,
onDismissRequest: () -> Unit,
modifier: Modifier = Modifier,
offset: DpOffset = DpOffset(0.dp, 0.dp),
scrollState: ScrollState = rememberScrollState(),
properties: PopupProperties = PopupProperties(focusable = true),
content: @Composable ColumnScope.() -> Unit
)

/**
* <a href="https://material.io/components/menus#dropdown-menu" class="external" target="_blank">Material Design dropdown menu</a> item.
*
*
* Example usage:
* @sample androidx.compose.material.samples.MenuSample
*
* @param onClick Called when the menu item was clicked
* @param modifier The modifier to be applied to the menu item
* @param enabled Controls the enabled state of the menu item - when `false`, the menu item
* will not be clickable and [onClick] will not be invoked
* @param contentPadding the padding applied to the content of this menu item
* @param interactionSource the [MutableInteractionSource] representing the stream of
* [Interaction]s for this DropdownMenuItem. You can create and pass in your own remembered
* [MutableInteractionSource] if you want to observe [Interaction]s and customize the
* appearance / behavior of this DropdownMenuItem in different [Interaction]s.
*/
@Composable
expect fun DropdownMenuItem(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable RowScope.() -> Unit
)

@Composable
internal fun DropdownMenuContent(
expandedStates: MutableTransitionState<Boolean>,
Expand Down

0 comments on commit 8f1df5e

Please sign in to comment.