mirror of
https://github.com/BetterAndroid/FlexiUI.git
synced 2025-09-07 19:14:12 +08:00
feat: add Interaction and move ripple effect with name "rippleColor"
This commit is contained in:
@@ -25,14 +25,11 @@ package com.highcapable.flexiui.component
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.selection.toggleable
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.Immutable
|
||||
@@ -49,12 +46,14 @@ import androidx.compose.ui.unit.Dp
|
||||
import com.highcapable.flexiui.LocalColors
|
||||
import com.highcapable.flexiui.LocalShapes
|
||||
import com.highcapable.flexiui.LocalSizes
|
||||
import com.highcapable.flexiui.interaction.rippleClickable
|
||||
import com.highcapable.flexiui.interaction.rippleToggleable
|
||||
import com.highcapable.flexiui.utils.borderOrNot
|
||||
import com.highcapable.flexiui.utils.orElse
|
||||
|
||||
@Immutable
|
||||
data class ButtonColors(
|
||||
val fillColor: Color,
|
||||
val rippleColor: Color,
|
||||
val contentColor: Color,
|
||||
val backgroundColor: Color
|
||||
)
|
||||
@@ -78,12 +77,12 @@ fun Button(
|
||||
content: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
var sModifier = modifier.clip(shape = shape)
|
||||
sModifier = if (enabled) sModifier.clickable(
|
||||
onClick = onClick,
|
||||
sModifier = if (enabled) sModifier.rippleClickable(
|
||||
enabled = enabled,
|
||||
role = Role.Button,
|
||||
indication = rememberRipple(color = colors.fillColor),
|
||||
interactionSource = interactionSource
|
||||
rippleColor = colors.rippleColor,
|
||||
interactionSource = interactionSource,
|
||||
onClick = onClick
|
||||
) else sModifier.alpha(0.5f)
|
||||
sModifier = sModifier.background(color = colors.backgroundColor, shape = shape)
|
||||
sModifier = sModifier.borderOrNot(border = border, shape = shape)
|
||||
@@ -117,18 +116,19 @@ fun Button(
|
||||
fun IconButton(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
fillColor: Color = Button.colors.fillColor,
|
||||
rippleColor: Color = Button.colors.rippleColor,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier.clickable(
|
||||
onClick = onClick,
|
||||
modifier = modifier.rippleClickable(
|
||||
rippleColor = rippleColor,
|
||||
bounded = false,
|
||||
enabled = enabled,
|
||||
role = Role.Button,
|
||||
interactionSource = interactionSource,
|
||||
indication = rememberRipple(bounded = false, color = fillColor)
|
||||
onClick = onClick
|
||||
),
|
||||
contentAlignment = Alignment.Center,
|
||||
) { content() }
|
||||
@@ -139,19 +139,20 @@ fun IconToggleButton(
|
||||
checked: Boolean,
|
||||
onCheckedChange: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
fillColor: Color = Button.colors.fillColor,
|
||||
rippleColor: Color = Button.colors.rippleColor,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier.toggleable(
|
||||
modifier = modifier.rippleToggleable(
|
||||
value = checked,
|
||||
rippleColor = rippleColor,
|
||||
bounded = false,
|
||||
onValueChange = onCheckedChange,
|
||||
enabled = enabled,
|
||||
role = Role.Checkbox,
|
||||
interactionSource = interactionSource,
|
||||
indication = rememberRipple(bounded = false, color = fillColor)
|
||||
interactionSource = interactionSource
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) { content() }
|
||||
@@ -214,7 +215,7 @@ private fun defaultButtonShape() = LocalShapes.current.tertiary
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultButtonInBoxColors() = ButtonColors(
|
||||
fillColor = LocalColors.current.themeSecondary,
|
||||
rippleColor = LocalColors.current.themeSecondary,
|
||||
contentColor = LocalColors.current.textPrimary,
|
||||
backgroundColor = LocalColors.current.foregroundSecondary
|
||||
)
|
||||
@@ -222,7 +223,7 @@ private fun defaultButtonInBoxColors() = ButtonColors(
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultButtonOutBoxColors() = ButtonColors(
|
||||
fillColor = LocalColors.current.foregroundSecondary,
|
||||
rippleColor = LocalColors.current.foregroundSecondary,
|
||||
contentColor = Color.White,
|
||||
backgroundColor = LocalColors.current.themePrimary
|
||||
)
|
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Flexi UI - A flexible and useful UI component library.
|
||||
* Copyright (C) 2019-2023 HighCapable
|
||||
* https://github.com/BetterAndroid/FlexiUI
|
||||
*
|
||||
* Apache License Version 2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is created by fankes on 2023/11/10.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.highcapable.flexiui.interaction
|
||||
|
||||
import androidx.compose.foundation.Indication
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import com.highcapable.flexiui.LocalColors
|
||||
import androidx.compose.foundation.clickable as foundationClickable
|
||||
import androidx.compose.foundation.selection.toggleable as foundationToggleable
|
||||
|
||||
@Composable
|
||||
fun Modifier.clickable(
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
indication: Indication? = null,
|
||||
enabled: Boolean = true,
|
||||
onClickLabel: String? = null,
|
||||
role: Role? = null,
|
||||
onClick: () -> Unit
|
||||
) = foundationClickable(interactionSource, indication, enabled, onClickLabel, role, onClick)
|
||||
|
||||
@Composable
|
||||
fun Modifier.toggleable(
|
||||
value: Boolean,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
indication: Indication? = null,
|
||||
enabled: Boolean = true,
|
||||
role: Role? = null,
|
||||
onValueChange: (Boolean) -> Unit
|
||||
) = foundationToggleable(value, interactionSource, indication, enabled, role, onValueChange)
|
||||
|
||||
@Composable
|
||||
fun Modifier.rippleClickable(
|
||||
rippleColor: Color = Interaction.rippleColor,
|
||||
bounded: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
enabled: Boolean = true,
|
||||
onClickLabel: String? = null,
|
||||
role: Role? = null,
|
||||
onClick: () -> Unit
|
||||
) = clickable(
|
||||
onClick = onClick,
|
||||
interactionSource = interactionSource,
|
||||
indication = rememberRipple(bounded = bounded, color = rippleColor),
|
||||
enabled = enabled,
|
||||
onClickLabel = onClickLabel,
|
||||
role = role
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun Modifier.rippleToggleable(
|
||||
value: Boolean,
|
||||
rippleColor: Color = Interaction.rippleColor,
|
||||
bounded: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
enabled: Boolean = true,
|
||||
role: Role? = null,
|
||||
onValueChange: (Boolean) -> Unit
|
||||
) = toggleable(
|
||||
value = value,
|
||||
interactionSource = interactionSource,
|
||||
indication = rememberRipple(bounded = bounded, color = rippleColor),
|
||||
enabled = enabled,
|
||||
role = role,
|
||||
onValueChange = onValueChange
|
||||
)
|
||||
|
||||
object Interaction {
|
||||
val rippleColor: Color
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = defaultInteractionRippleColor()
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultInteractionRippleColor() = LocalColors.current.themeSecondary
|
@@ -27,7 +27,6 @@ import androidx.compose.foundation.ContextMenuItem
|
||||
import androidx.compose.foundation.ContextMenuRepresentation
|
||||
import androidx.compose.foundation.ContextMenuState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
@@ -40,7 +39,6 @@ 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
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
@@ -76,13 +74,13 @@ import androidx.compose.ui.window.rememberPopupPositionProviderAtPosition
|
||||
import com.highcapable.flexiui.LocalColors
|
||||
import com.highcapable.flexiui.LocalShapes
|
||||
import com.highcapable.flexiui.LocalSizes
|
||||
import com.highcapable.flexiui.interaction.rippleClickable
|
||||
import com.highcapable.flexiui.utils.orElse
|
||||
import java.awt.event.KeyEvent
|
||||
|
||||
@Immutable
|
||||
data class ContextMenuStyle(
|
||||
val backgroundColor: Color,
|
||||
val fillColor: Color,
|
||||
val textColor: Color,
|
||||
val padding: Dp,
|
||||
val shadowSize: Dp,
|
||||
@@ -130,7 +128,6 @@ internal class DesktopContextMenuRepresentation(private val style: ContextMenuSt
|
||||
) {
|
||||
items().forEach { item ->
|
||||
MenuItemContent(
|
||||
fillColor = style.fillColor,
|
||||
shape = shape,
|
||||
onClick = {
|
||||
state.status = ContextMenuState.Status.Closed
|
||||
@@ -146,7 +143,6 @@ internal class DesktopContextMenuRepresentation(private val style: ContextMenuSt
|
||||
|
||||
@Composable
|
||||
private fun MenuItemContent(
|
||||
fillColor: Color,
|
||||
shape: Shape,
|
||||
onClick: () -> Unit,
|
||||
content: @Composable RowScope.() -> Unit
|
||||
@@ -155,9 +151,8 @@ private fun MenuItemContent(
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clip(shape)
|
||||
.clickable(
|
||||
.rippleClickable(
|
||||
onClick = onClick,
|
||||
indication = rememberRipple(color = fillColor),
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
)
|
||||
.onHover { hovered = it }
|
||||
@@ -200,7 +195,6 @@ object DesktopContextMenu {
|
||||
val LocalContextMenuStyle = compositionLocalOf {
|
||||
ContextMenuStyle(
|
||||
backgroundColor = Color.Unspecified,
|
||||
fillColor = Color.Unspecified,
|
||||
textColor = Color.Unspecified,
|
||||
padding = Dp.Unspecified,
|
||||
shadowSize = Dp.Unspecified,
|
||||
@@ -212,7 +206,6 @@ val LocalContextMenuStyle = compositionLocalOf {
|
||||
@ReadOnlyComposable
|
||||
internal fun defaultContextMenuStyle() = ContextMenuStyle(
|
||||
backgroundColor = LocalContextMenuStyle.current.backgroundColor.orElse() ?: LocalColors.current.foregroundPrimary,
|
||||
fillColor = LocalContextMenuStyle.current.fillColor.orElse() ?: LocalColors.current.themeSecondary,
|
||||
textColor = LocalContextMenuStyle.current.textColor.orElse() ?: LocalColors.current.textPrimary,
|
||||
padding = LocalContextMenuStyle.current.padding.orElse() ?: LocalSizes.current.spacingTertiary,
|
||||
shadowSize = LocalContextMenuStyle.current.shadowSize.orElse() ?: LocalSizes.current.zoomSizeTertiary,
|
||||
|
Reference in New Issue
Block a user