mirror of
https://github.com/BetterAndroid/FlexiUI.git
synced 2025-09-07 19:14:12 +08:00
refactor: support code comments and some tweaks for all components
This commit is contained in:
@@ -30,6 +30,10 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import com.highcapable.betterandroid.ui.extension.component.feature.SystemColors
|
||||
import com.highcapable.betterandroid.ui.extension.graphics.mixColorOf
|
||||
|
||||
/**
|
||||
* Whether dynamic color is available for current system.
|
||||
* @return [Boolean]
|
||||
*/
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
actual fun isDynamicColorAvailable() = SystemColors.isAvailable
|
||||
@@ -46,8 +50,7 @@ internal actual val DynamicLightColors
|
||||
themeSecondary = Color(DynamicColors.materialDynamicPrimary(60)).copy(alpha = 0.65f),
|
||||
themeTertiary = Color(DynamicColors.materialDynamicPrimary(60)).copy(alpha = 0.15f),
|
||||
textPrimary = DefaultLightColors.textPrimary,
|
||||
textSecondary = DefaultLightColors.textSecondary,
|
||||
isLight = true
|
||||
textSecondary = DefaultLightColors.textSecondary
|
||||
) else DefaultLightColors
|
||||
|
||||
internal actual val DynamicDarkColors
|
||||
@@ -62,8 +65,7 @@ internal actual val DynamicDarkColors
|
||||
themeSecondary = Color(DynamicColors.materialDynamicSecondary(60)).copy(alpha = 0.65f),
|
||||
themeTertiary = Color(DynamicColors.materialDynamicSecondary(60)).copy(alpha = 0.25f),
|
||||
textPrimary = DefaultDarkColors.textPrimary,
|
||||
textSecondary = DefaultDarkColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultDarkColors.textSecondary
|
||||
) else DefaultDarkColors
|
||||
|
||||
internal actual val DynamicBlackColors
|
||||
@@ -78,8 +80,7 @@ internal actual val DynamicBlackColors
|
||||
themeSecondary = Color(DynamicColors.materialDynamicSecondary(60)).copy(alpha = 0.65f),
|
||||
themeTertiary = Color(DynamicColors.materialDynamicSecondary(60)).copy(alpha = 0.27f),
|
||||
textPrimary = DefaultBlackColors.textPrimary,
|
||||
textSecondary = DefaultBlackColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultBlackColors.textSecondary
|
||||
) else DefaultBlackColors
|
||||
|
||||
private val DynamicColors
|
||||
|
@@ -29,6 +29,9 @@ import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
/**
|
||||
* Colors defines for Flexi UI.
|
||||
*/
|
||||
@Stable
|
||||
data class Colors(
|
||||
var backgroundPrimary: Color,
|
||||
@@ -39,8 +42,7 @@ data class Colors(
|
||||
var themeSecondary: Color,
|
||||
var themeTertiary: Color,
|
||||
var textPrimary: Color,
|
||||
var textSecondary: Color,
|
||||
var isLight: Boolean
|
||||
var textSecondary: Color
|
||||
)
|
||||
|
||||
@get:Composable
|
||||
@@ -64,8 +66,7 @@ internal val DefaultLightColors = Colors(
|
||||
themeSecondary = Color(0xA6777777),
|
||||
themeTertiary = Color(0x27777777),
|
||||
textPrimary = Color(0xFF323B42),
|
||||
textSecondary = Color(0xFF777777),
|
||||
isLight = true
|
||||
textSecondary = Color(0xFF777777)
|
||||
)
|
||||
|
||||
internal val DefaultDarkColors = Colors(
|
||||
@@ -77,8 +78,7 @@ internal val DefaultDarkColors = Colors(
|
||||
themeSecondary = Color(0xA6888888),
|
||||
themeTertiary = Color(0x40888888),
|
||||
textPrimary = Color(0xFFE3E3E3),
|
||||
textSecondary = Color(0xFFBBBBBB),
|
||||
isLight = false
|
||||
textSecondary = Color(0xFFBBBBBB)
|
||||
)
|
||||
|
||||
internal val DefaultBlackColors = Colors(
|
||||
@@ -90,8 +90,7 @@ internal val DefaultBlackColors = Colors(
|
||||
themeSecondary = Color(0xA65B5B5B),
|
||||
themeTertiary = Color(0x455B5B5B),
|
||||
textPrimary = DefaultDarkColors.textPrimary,
|
||||
textSecondary = DefaultDarkColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultDarkColors.textSecondary
|
||||
)
|
||||
|
||||
private val RedLightColors = Colors(
|
||||
@@ -103,8 +102,7 @@ private val RedLightColors = Colors(
|
||||
themeSecondary = Color(0xA6FF5545),
|
||||
themeTertiary = Color(0x27FF5545),
|
||||
textPrimary = DefaultLightColors.textPrimary,
|
||||
textSecondary = DefaultLightColors.textSecondary,
|
||||
isLight = true
|
||||
textSecondary = DefaultLightColors.textSecondary
|
||||
)
|
||||
|
||||
private val PinkLightColors = Colors(
|
||||
@@ -116,8 +114,7 @@ private val PinkLightColors = Colors(
|
||||
themeSecondary = Color(0xA6FF4E7C),
|
||||
themeTertiary = Color(0x27FF4E7C),
|
||||
textPrimary = DefaultLightColors.textPrimary,
|
||||
textSecondary = DefaultLightColors.textSecondary,
|
||||
isLight = true
|
||||
textSecondary = DefaultLightColors.textSecondary
|
||||
)
|
||||
|
||||
private val PurpleLightColors = Colors(
|
||||
@@ -129,8 +126,7 @@ private val PurpleLightColors = Colors(
|
||||
themeSecondary = Color(0xA6A476FF),
|
||||
themeTertiary = Color(0x27A476FF),
|
||||
textPrimary = DefaultLightColors.textPrimary,
|
||||
textSecondary = DefaultLightColors.textSecondary,
|
||||
isLight = true
|
||||
textSecondary = DefaultLightColors.textSecondary
|
||||
)
|
||||
|
||||
private val OrangeLightColors = Colors(
|
||||
@@ -142,8 +138,7 @@ private val OrangeLightColors = Colors(
|
||||
themeSecondary = Color(0xA6D27C00),
|
||||
themeTertiary = Color(0x27D27C00),
|
||||
textPrimary = DefaultLightColors.textPrimary,
|
||||
textSecondary = DefaultLightColors.textSecondary,
|
||||
isLight = true
|
||||
textSecondary = DefaultLightColors.textSecondary
|
||||
)
|
||||
|
||||
private val YellowLightColors = Colors(
|
||||
@@ -155,8 +150,7 @@ private val YellowLightColors = Colors(
|
||||
themeSecondary = Color(0xA6BA8800),
|
||||
themeTertiary = Color(0x27BA8800),
|
||||
textPrimary = DefaultLightColors.textPrimary,
|
||||
textSecondary = DefaultLightColors.textSecondary,
|
||||
isLight = true
|
||||
textSecondary = DefaultLightColors.textSecondary
|
||||
)
|
||||
|
||||
private val GreenLightColors = Colors(
|
||||
@@ -168,8 +162,7 @@ private val GreenLightColors = Colors(
|
||||
themeSecondary = Color(0xA65B9E7A),
|
||||
themeTertiary = Color(0x275B9E7A),
|
||||
textPrimary = DefaultLightColors.textPrimary,
|
||||
textSecondary = DefaultLightColors.textSecondary,
|
||||
isLight = true
|
||||
textSecondary = DefaultLightColors.textSecondary
|
||||
)
|
||||
|
||||
private val BlueLightColors = Colors(
|
||||
@@ -181,8 +174,7 @@ private val BlueLightColors = Colors(
|
||||
themeSecondary = Color(0xA60099DF),
|
||||
themeTertiary = Color(0x270099DF),
|
||||
textPrimary = DefaultLightColors.textPrimary,
|
||||
textSecondary = DefaultLightColors.textSecondary,
|
||||
isLight = true
|
||||
textSecondary = DefaultLightColors.textSecondary
|
||||
)
|
||||
|
||||
private val RedDarkColors = Colors(
|
||||
@@ -194,8 +186,7 @@ private val RedDarkColors = Colors(
|
||||
themeSecondary = Color(0xA6B9856D),
|
||||
themeTertiary = Color(0x40B9856D),
|
||||
textPrimary = DefaultDarkColors.textPrimary,
|
||||
textSecondary = DefaultDarkColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultDarkColors.textSecondary
|
||||
)
|
||||
|
||||
private val PinkDarkColors = Colors(
|
||||
@@ -207,8 +198,7 @@ private val PinkDarkColors = Colors(
|
||||
themeSecondary = Color(0xA6BA837B),
|
||||
themeTertiary = Color(0x40BA837B),
|
||||
textPrimary = DefaultDarkColors.textPrimary,
|
||||
textSecondary = DefaultDarkColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultDarkColors.textSecondary
|
||||
)
|
||||
|
||||
private val PurpleDarkColors = Colors(
|
||||
@@ -220,8 +210,7 @@ private val PurpleDarkColors = Colors(
|
||||
themeSecondary = Color(0xA69F88AD),
|
||||
themeTertiary = Color(0x409F88AD),
|
||||
textPrimary = DefaultDarkColors.textPrimary,
|
||||
textSecondary = DefaultDarkColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultDarkColors.textSecondary
|
||||
)
|
||||
|
||||
private val OrangeDarkColors = Colors(
|
||||
@@ -233,8 +222,7 @@ private val OrangeDarkColors = Colors(
|
||||
themeSecondary = Color(0xA6AE8B5D),
|
||||
themeTertiary = Color(0x40AE8B5D),
|
||||
textPrimary = DefaultDarkColors.textPrimary,
|
||||
textSecondary = DefaultDarkColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultDarkColors.textSecondary
|
||||
)
|
||||
|
||||
private val YellowDarkColors = Colors(
|
||||
@@ -246,8 +234,7 @@ private val YellowDarkColors = Colors(
|
||||
themeSecondary = Color(0xA6A18F5C),
|
||||
themeTertiary = Color(0x40A18F5C),
|
||||
textPrimary = DefaultDarkColors.textPrimary,
|
||||
textSecondary = DefaultDarkColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultDarkColors.textSecondary
|
||||
)
|
||||
|
||||
private val GreenDarkColors = Colors(
|
||||
@@ -259,8 +246,7 @@ private val GreenDarkColors = Colors(
|
||||
themeSecondary = Color(0xA67F9687),
|
||||
themeTertiary = Color(0x407F9687),
|
||||
textPrimary = DefaultDarkColors.textPrimary,
|
||||
textSecondary = DefaultDarkColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultDarkColors.textSecondary
|
||||
)
|
||||
|
||||
private val BlueDarkColors = Colors(
|
||||
@@ -272,8 +258,7 @@ private val BlueDarkColors = Colors(
|
||||
themeSecondary = Color(0xA68091B1),
|
||||
themeTertiary = Color(0x408091B1),
|
||||
textPrimary = DefaultDarkColors.textPrimary,
|
||||
textSecondary = DefaultDarkColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultDarkColors.textSecondary
|
||||
)
|
||||
|
||||
private val RedBlackColors = Colors(
|
||||
@@ -285,8 +270,7 @@ private val RedBlackColors = Colors(
|
||||
themeSecondary = Color(0xA6B9856D),
|
||||
themeTertiary = Color(0x45B9856D),
|
||||
textPrimary = DefaultBlackColors.textPrimary,
|
||||
textSecondary = DefaultBlackColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultBlackColors.textSecondary
|
||||
)
|
||||
|
||||
private val PinkBlackColors = Colors(
|
||||
@@ -298,8 +282,7 @@ private val PinkBlackColors = Colors(
|
||||
themeSecondary = Color(0xA6BA837B),
|
||||
themeTertiary = Color(0x45BA837B),
|
||||
textPrimary = DefaultBlackColors.textPrimary,
|
||||
textSecondary = DefaultBlackColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultBlackColors.textSecondary
|
||||
)
|
||||
|
||||
private val PurpleBlackColors = Colors(
|
||||
@@ -311,8 +294,7 @@ private val PurpleBlackColors = Colors(
|
||||
themeSecondary = Color(0xA69F88AD),
|
||||
themeTertiary = Color(0x459F88AD),
|
||||
textPrimary = DefaultBlackColors.textPrimary,
|
||||
textSecondary = DefaultBlackColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultBlackColors.textSecondary
|
||||
)
|
||||
|
||||
private val OrangeBlackColors = Colors(
|
||||
@@ -324,8 +306,7 @@ private val OrangeBlackColors = Colors(
|
||||
themeSecondary = Color(0xA6AE8B5D),
|
||||
themeTertiary = Color(0x45AE8B5D),
|
||||
textPrimary = DefaultBlackColors.textPrimary,
|
||||
textSecondary = DefaultBlackColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultBlackColors.textSecondary
|
||||
)
|
||||
|
||||
private val YellowBlackColors = Colors(
|
||||
@@ -337,8 +318,7 @@ private val YellowBlackColors = Colors(
|
||||
themeSecondary = Color(0xA6A18F5C),
|
||||
themeTertiary = Color(0x45A18F5C),
|
||||
textPrimary = DefaultBlackColors.textPrimary,
|
||||
textSecondary = DefaultBlackColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultBlackColors.textSecondary
|
||||
)
|
||||
|
||||
private val GreenBlackColors = Colors(
|
||||
@@ -350,8 +330,7 @@ private val GreenBlackColors = Colors(
|
||||
themeSecondary = Color(0xA67F9687),
|
||||
themeTertiary = Color(0x457F9687),
|
||||
textPrimary = DefaultBlackColors.textPrimary,
|
||||
textSecondary = DefaultBlackColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultBlackColors.textSecondary
|
||||
)
|
||||
|
||||
private val BlueBlackColors = Colors(
|
||||
@@ -363,14 +342,24 @@ private val BlueBlackColors = Colors(
|
||||
themeSecondary = Color(0xA68091B1),
|
||||
themeTertiary = Color(0x458091B1),
|
||||
textPrimary = DefaultBlackColors.textPrimary,
|
||||
textSecondary = DefaultBlackColors.textSecondary,
|
||||
isLight = false
|
||||
textSecondary = DefaultBlackColors.textSecondary
|
||||
)
|
||||
|
||||
/**
|
||||
* Whether dynamic color is available for current system.
|
||||
* @return [Boolean]
|
||||
*/
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
expect fun isDynamicColorAvailable(): Boolean
|
||||
|
||||
/**
|
||||
* Returns a dynamic color scheme provided by system.
|
||||
*
|
||||
* You can use [isDynamicColorAvailable] check it first, otherwise it will return default colors.
|
||||
* @param darkMode whether to use dark mode color scheme.
|
||||
* @param blackDarkMode requires [darkMode] is true, whether to use a pure black color scheme.
|
||||
*/
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
fun dynamicColors(darkMode: Boolean = false, blackDarkMode: Boolean = false) = when {
|
||||
@@ -378,41 +367,81 @@ fun dynamicColors(darkMode: Boolean = false, blackDarkMode: Boolean = false) = w
|
||||
else -> DynamicLightColors
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a default color scheme.
|
||||
* @param darkMode whether to use dark mode color scheme.
|
||||
* @param blackDarkMode requires [darkMode] is true, whether to use a pure black color scheme.
|
||||
*/
|
||||
fun defaultColors(darkMode: Boolean = false, blackDarkMode: Boolean = false) = when {
|
||||
darkMode -> if (blackDarkMode) DefaultBlackColors else DefaultDarkColors
|
||||
else -> DefaultLightColors
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a red color scheme.
|
||||
* @param darkMode whether to use dark mode color scheme.
|
||||
* @param blackDarkMode requires [darkMode] is true, whether to use a pure black color scheme.
|
||||
*/
|
||||
fun redColors(darkMode: Boolean = false, blackDarkMode: Boolean = false) = when {
|
||||
darkMode -> if (blackDarkMode) RedBlackColors else RedDarkColors
|
||||
else -> RedLightColors
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pink color scheme.
|
||||
* @param darkMode whether to use dark mode color scheme.
|
||||
* @param blackDarkMode requires [darkMode] is true, whether to use a pure black color scheme.
|
||||
*/
|
||||
fun pinkColors(darkMode: Boolean = false, blackDarkMode: Boolean = false) = when {
|
||||
darkMode -> if (blackDarkMode) PinkBlackColors else PinkDarkColors
|
||||
else -> PinkLightColors
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a purple color scheme.
|
||||
* @param darkMode whether to use dark mode color scheme.
|
||||
* @param blackDarkMode requires [darkMode] is true, whether to use a pure black color scheme.
|
||||
*/
|
||||
fun purpleColors(darkMode: Boolean = false, blackDarkMode: Boolean = false) = when {
|
||||
darkMode -> if (blackDarkMode) PurpleBlackColors else PurpleDarkColors
|
||||
else -> PurpleLightColors
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a orange color scheme.
|
||||
* @param darkMode whether to use dark mode color scheme.
|
||||
* @param blackDarkMode requires [darkMode] is true, whether to use a pure black color scheme.
|
||||
*/
|
||||
fun orangeColors(darkMode: Boolean = false, blackDarkMode: Boolean = false) = when {
|
||||
darkMode -> if (blackDarkMode) OrangeBlackColors else OrangeDarkColors
|
||||
else -> OrangeLightColors
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a yellow color scheme.
|
||||
* @param darkMode whether to use dark mode color scheme.
|
||||
* @param blackDarkMode requires [darkMode] is true, whether to use a pure black color scheme.
|
||||
*/
|
||||
fun yellowColors(darkMode: Boolean = false, blackDarkMode: Boolean = false) = when {
|
||||
darkMode -> if (blackDarkMode) YellowBlackColors else YellowDarkColors
|
||||
else -> YellowLightColors
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a green color scheme.
|
||||
* @param darkMode whether to use dark mode color scheme.
|
||||
* @param blackDarkMode requires [darkMode] is true, whether to use a pure black color scheme.
|
||||
*/
|
||||
fun greenColors(darkMode: Boolean = false, blackDarkMode: Boolean = false) = when {
|
||||
darkMode -> if (blackDarkMode) GreenBlackColors else GreenDarkColors
|
||||
else -> GreenLightColors
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a blue color scheme.
|
||||
* @param darkMode whether to use dark mode color scheme.
|
||||
* @param blackDarkMode requires [darkMode] is true, whether to use a pure black color scheme.
|
||||
*/
|
||||
fun blueColors(darkMode: Boolean = false, blackDarkMode: Boolean = false) = when {
|
||||
darkMode -> if (blackDarkMode) BlueBlackColors else BlueDarkColors
|
||||
else -> BlueLightColors
|
||||
|
@@ -27,6 +27,15 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
|
||||
/**
|
||||
* Customize Flexi UI theme styles.
|
||||
*
|
||||
* Use this function to provide your own theme styles to the content.
|
||||
* @param colors the colors, default is [FlexiTheme.colors].
|
||||
* @param shapes the shapes, default is [FlexiTheme.shapes].
|
||||
* @param typography the typography, default is [FlexiTheme.typography].
|
||||
* @param content the content.
|
||||
*/
|
||||
@Composable
|
||||
fun FlexiTheme(
|
||||
colors: Colors = FlexiTheme.colors,
|
||||
@@ -37,6 +46,17 @@ fun FlexiTheme(
|
||||
FlexiTheme(colors, shapes, typography, FlexiTheme.sizes, content)
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize Flexi UI theme styles.
|
||||
*
|
||||
* Use this function to provide your own theme styles to the content.
|
||||
*
|
||||
* - Note: The [sizes] is experimental for now, its may be change in the future.
|
||||
* @param colors the colors, default is [FlexiTheme.colors].
|
||||
* @param shapes the shapes, default is [FlexiTheme.shapes].
|
||||
* @param sizes the sizes.
|
||||
* @param typography the typography, default is [FlexiTheme.typography].
|
||||
*/
|
||||
@Composable
|
||||
fun FlexiTheme(
|
||||
colors: Colors = FlexiTheme.colors,
|
||||
@@ -53,6 +73,9 @@ fun FlexiTheme(
|
||||
) { FlexiThemeContent(content) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Defaults of Flexi UI theme styles.
|
||||
*/
|
||||
object FlexiTheme {
|
||||
val colors: Colors
|
||||
@Composable
|
||||
|
@@ -30,6 +30,9 @@ import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Shapes defines for Flexi UI.
|
||||
*/
|
||||
@Immutable
|
||||
data class Shapes(
|
||||
val primary: CornerBasedShape,
|
||||
|
@@ -28,6 +28,9 @@ import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Sizes defines for Flexi UI.
|
||||
*/
|
||||
@ExperimentalFlexiUISizesApi
|
||||
@Immutable
|
||||
data class Sizes(
|
||||
|
@@ -30,6 +30,9 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.em
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
/**
|
||||
* Typography defines for Flexi UI.
|
||||
*/
|
||||
@Immutable
|
||||
data class Typography(
|
||||
val titlePrimary: TextStyle,
|
||||
|
@@ -56,6 +56,12 @@ import com.highcapable.flexiui.resources.Icons
|
||||
import com.highcapable.flexiui.resources.icon.ArrowNaviUp
|
||||
import com.highcapable.flexiui.resources.icon.FinishClose
|
||||
|
||||
/**
|
||||
* Colors defines for action bar.
|
||||
* @param titleTextColor the title text color.
|
||||
* @param subTextColor the sub text color.
|
||||
* @param actionContentColor the action content color, usually for icon tint and text color.
|
||||
*/
|
||||
@Immutable
|
||||
data class ActionBarColors(
|
||||
val titleTextColor: Color,
|
||||
@@ -63,6 +69,16 @@ data class ActionBarColors(
|
||||
val actionContentColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for action bar.
|
||||
* @param padding the padding of content.
|
||||
* @param contentSpacing the spacing between the components of content.
|
||||
* @param titleTextStyle the title text style.
|
||||
* @param subTextStyle the sub text style.
|
||||
* @param actionIconSize the size of action icon.
|
||||
* @param actionIconPadding the padding of action icon.
|
||||
* @param actionContentMaxWidth the max width of actions content.
|
||||
*/
|
||||
@Immutable
|
||||
data class ActionBarStyle(
|
||||
val padding: ComponentPadding,
|
||||
@@ -74,6 +90,16 @@ data class ActionBarStyle(
|
||||
val actionContentMaxWidth: Dp
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI large action bar.
|
||||
* @see ActionBarDefaults
|
||||
* @param modifier the [Modifier] to be applied to this action bar.
|
||||
* @param colors the colors of this action bar, default is [ActionBarDefaults.colors].
|
||||
* @param style the style of this action bar, default is [ActionBarDefaults.style].
|
||||
* @param titleText the title text of this action bar, should typically be [Text].
|
||||
* @param subText the sub text of this action bar, should typically be [Text].
|
||||
* @param actions the actions displayed at the end of the action bar, should typically be [ActionBarScope.ActionIconButton].
|
||||
*/
|
||||
@Composable
|
||||
fun TopActionBar(
|
||||
modifier: Modifier = Modifier,
|
||||
@@ -96,6 +122,18 @@ fun TopActionBar(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI middle action bar.
|
||||
* @see TopActionBar
|
||||
* @param modifier the [Modifier] to be applied to this action bar.
|
||||
* @param colors the colors of this action bar, default is [ActionBarDefaults.colors].
|
||||
* @param style the style of this action bar, default is [ActionBarDefaults.style].
|
||||
* @param titleText the title text of this action bar, should typically be [Text].
|
||||
* @param subText the sub text of this action bar, should typically be [Text].
|
||||
* @param finishIcon the finish icon displayed at the start of the action bar, should typically be [ActionBarScope.FinishIconButton].
|
||||
* @param navigationIcon the navigation icon displayed at the start of the action bar, should typically be [ActionBarScope.NavigationIconButton].
|
||||
* @param actions the actions displayed at the end of the action bar, should typically be [ActionBarScope.ActionIconButton].
|
||||
*/
|
||||
@Composable
|
||||
fun ActionBar(
|
||||
modifier: Modifier = Modifier,
|
||||
@@ -120,6 +158,9 @@ fun ActionBar(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic action bar for internal use.
|
||||
*/
|
||||
@Composable
|
||||
private fun BasicActionBar(
|
||||
type: ActionBarType,
|
||||
@@ -133,8 +174,8 @@ private fun BasicActionBar(
|
||||
actions: @Composable (ActionBarScope.() -> Unit)?
|
||||
) {
|
||||
CompositionLocalProvider(LocalActionBarType provides type) {
|
||||
val currentColors = colors ?: ActionBar.colors
|
||||
val currentStyle = style ?: ActionBar.style
|
||||
val currentColors = colors ?: ActionBarDefaults.colors
|
||||
val currentStyle = style ?: ActionBarDefaults.style
|
||||
Box(modifier = modifier.padding(currentStyle.padding)) {
|
||||
ActionBarImpl(
|
||||
type = type,
|
||||
@@ -150,15 +191,27 @@ private fun BasicActionBar(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A scope for action bar.
|
||||
*/
|
||||
@Stable
|
||||
interface ActionBarScope {
|
||||
|
||||
/**
|
||||
* Action bar's finish icon button.
|
||||
* @param onClick the callback when the icon button is clicked.
|
||||
* @param modifier the [Modifier] to be applied to this icon button.
|
||||
* @param colors the colors of this icon button, default is [IconButtonDefaults.colors].
|
||||
* @param style the style of this icon button, default is [IconButtonDefaults.style].
|
||||
* @param enabled whether this icon button is enabled, default is true.
|
||||
* @param interactionSource the interaction source of this icon button.
|
||||
*/
|
||||
@Composable
|
||||
fun FinishIconButton(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: ButtonColors = IconButton.colors,
|
||||
style: ButtonStyle = IconButton.style,
|
||||
colors: ButtonColors = IconButtonDefaults.colors,
|
||||
style: ButtonStyle = IconButtonDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
@@ -172,12 +225,21 @@ interface ActionBarScope {
|
||||
) { Icon(imageVector = Icons.FinishClose) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Action bar's navigation icon button.
|
||||
* @param onClick the callback when the icon button is clicked.
|
||||
* @param modifier the [Modifier] to be applied to this icon button.
|
||||
* @param colors the colors of this icon button, default is [IconButtonDefaults.colors].
|
||||
* @param style the style of this icon button, default is [IconButtonDefaults.style].
|
||||
* @param enabled whether this icon button is enabled, default is true.
|
||||
* @param interactionSource the interaction source of this icon button.
|
||||
*/
|
||||
@Composable
|
||||
fun NavigationIconButton(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: ButtonColors = IconButton.colors,
|
||||
style: ButtonStyle = IconButton.style,
|
||||
colors: ButtonColors = IconButtonDefaults.colors,
|
||||
style: ButtonStyle = IconButtonDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
@@ -191,12 +253,22 @@ interface ActionBarScope {
|
||||
) { Icon(imageVector = Icons.ArrowNaviUp) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Action bar's action icon button.
|
||||
* @param onClick the callback when the icon button is clicked.
|
||||
* @param modifier the [Modifier] to be applied to this icon button.
|
||||
* @param colors the colors of this icon button, default is [IconButtonDefaults.colors].
|
||||
* @param style the style of this icon button, default is [IconButtonDefaults.style].
|
||||
* @param enabled whether this icon button is enabled, default is true.
|
||||
* @param interactionSource the interaction source of this icon button.
|
||||
* @param content the content of the [ActionIconButton], should typically be [Icon].
|
||||
*/
|
||||
@Composable
|
||||
fun ActionIconButton(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: ButtonColors = IconButton.colors,
|
||||
style: ButtonStyle = IconButton.style,
|
||||
colors: ButtonColors = IconButtonDefaults.colors,
|
||||
style: ButtonStyle = IconButtonDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable () -> Unit
|
||||
@@ -214,6 +286,9 @@ interface ActionBarScope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action bar's implementation.
|
||||
*/
|
||||
@Immutable
|
||||
private class ActionBarImpl(
|
||||
val type: ActionBarType,
|
||||
@@ -226,6 +301,7 @@ private class ActionBarImpl(
|
||||
val actions: @Composable (ActionBarScope.() -> Unit)?
|
||||
) : ActionBarScope {
|
||||
|
||||
/** Build action bar's content. */
|
||||
@Composable
|
||||
fun Content() {
|
||||
BoxWithConstraints(modifier = Modifier.fillMaxWidth()) {
|
||||
@@ -250,6 +326,7 @@ private class ActionBarImpl(
|
||||
}
|
||||
}
|
||||
|
||||
/** Build action bar's start content. */
|
||||
@Composable
|
||||
private fun StartContent() {
|
||||
if (type == ActionBarType.MIDDLE && (finishIcon != null || navigationIcon != null))
|
||||
@@ -264,6 +341,7 @@ private class ActionBarImpl(
|
||||
}
|
||||
}
|
||||
|
||||
/** Build action bar's center content. */
|
||||
@Composable
|
||||
private fun CenterContent() {
|
||||
Column(
|
||||
@@ -285,6 +363,7 @@ private class ActionBarImpl(
|
||||
}
|
||||
}
|
||||
|
||||
/** Build action bar's end content. */
|
||||
@Composable
|
||||
private fun EndContent() {
|
||||
actions?.also { content ->
|
||||
@@ -297,6 +376,7 @@ private class ActionBarImpl(
|
||||
}
|
||||
}
|
||||
|
||||
/** Provided the style for action bar's content. */
|
||||
@Composable
|
||||
private fun ContentStyle(
|
||||
color: Color,
|
||||
@@ -317,7 +397,10 @@ private val ActionBarScope.impl get() = this as? ActionBarImpl? ?: error("Could
|
||||
@Stable
|
||||
private enum class ActionBarType { LARGE, MIDDLE }
|
||||
|
||||
object ActionBar {
|
||||
/**
|
||||
* Defaults of action bar.
|
||||
*/
|
||||
object ActionBarDefaults {
|
||||
val colors: ActionBarColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
|
@@ -55,6 +55,13 @@ import com.highcapable.flexiui.LocalColors
|
||||
import com.highcapable.flexiui.LocalShapes
|
||||
import com.highcapable.flexiui.LocalSizes
|
||||
|
||||
/**
|
||||
* Style defines for area box.
|
||||
* @param padding the padding of content.
|
||||
* @param shape the shape of the box.
|
||||
* @param border the border stroke of the box.
|
||||
* @param shadowSize the shadow size of the box.
|
||||
*/
|
||||
@Immutable
|
||||
data class AreaBoxStyle(
|
||||
val padding: ComponentPadding,
|
||||
@@ -63,12 +70,24 @@ data class AreaBoxStyle(
|
||||
val shadowSize: Dp
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI area box of [Box].
|
||||
* @see AreaRow
|
||||
* @see AreaColumn
|
||||
* @param modifier the [Modifier] to be applied to this area box.
|
||||
* @param initializer the [Modifier] initializer, earlies than [modifier].
|
||||
* @param color the background color of this area box, default is [AreaBoxDefaults.color].
|
||||
* @param style the style of this area box, default is [AreaBoxDefaults.style].
|
||||
* @param contentAlignment the alignment of the content inside this area box, default is [Alignment.TopStart].
|
||||
* @param propagateMinConstraints whether to propagate the min constraints from the content to this area box.
|
||||
* @param content the content of the [AreaBox].
|
||||
*/
|
||||
@Composable
|
||||
fun AreaBox(
|
||||
modifier: Modifier = Modifier,
|
||||
initializer: @Composable Modifier.() -> Modifier = { Modifier },
|
||||
color: Color = AreaBox.color,
|
||||
style: AreaBoxStyle = AreaBox.style,
|
||||
color: Color = AreaBoxDefaults.color,
|
||||
style: AreaBoxStyle = AreaBoxDefaults.style,
|
||||
contentAlignment: Alignment = Alignment.TopStart,
|
||||
propagateMinConstraints: Boolean = false,
|
||||
content: @Composable BoxScope.() -> Unit
|
||||
@@ -86,12 +105,24 @@ fun AreaBox(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI area box of [Row].
|
||||
* @see AreaColumn
|
||||
* @see AreaBox
|
||||
* @param modifier the [Modifier] to be applied to this area row.
|
||||
* @param initializer the [Modifier] initializer, earlies than [modifier].
|
||||
* @param color the background color of this area row, default is [AreaBoxDefaults.color].
|
||||
* @param style the style of this area row, default is [AreaBoxDefaults.style].
|
||||
* @param horizontalArrangement the horizontal arrangement of the content inside this area row, default is [Arrangement.Start].
|
||||
* @param verticalAlignment the vertical alignment of the content inside this area row, default is [Alignment.Top].
|
||||
* @param content the content of the [AreaRow].
|
||||
*/
|
||||
@Composable
|
||||
fun AreaRow(
|
||||
modifier: Modifier = Modifier,
|
||||
initializer: @Composable Modifier.() -> Modifier = { Modifier },
|
||||
color: Color = AreaBox.color,
|
||||
style: AreaBoxStyle = AreaBox.style,
|
||||
color: Color = AreaBoxDefaults.color,
|
||||
style: AreaBoxStyle = AreaBoxDefaults.style,
|
||||
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
|
||||
verticalAlignment: Alignment.Vertical = Alignment.Top,
|
||||
content: @Composable RowScope.() -> Unit
|
||||
@@ -109,12 +140,24 @@ fun AreaRow(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI area box of [Column].
|
||||
* @see AreaRow
|
||||
* @see AreaBox
|
||||
* @param modifier the [Modifier] to be applied to this area column.
|
||||
* @param initializer the [Modifier] initializer, earlies than [modifier].
|
||||
* @param color the background color of this area column, default is [AreaBoxDefaults.color].
|
||||
* @param style the style of this area column, default is [AreaBoxDefaults.style].
|
||||
* @param verticalArrangement the vertical arrangement of the content inside this area column, default is [Arrangement.Top].
|
||||
* @param horizontalAlignment the horizontal alignment of the content inside this area column, default is [Alignment.Start].
|
||||
* @param content the content of the [AreaColumn].
|
||||
*/
|
||||
@Composable
|
||||
fun AreaColumn(
|
||||
modifier: Modifier = Modifier,
|
||||
initializer: @Composable Modifier.() -> Modifier = { Modifier },
|
||||
color: Color = AreaBox.color,
|
||||
style: AreaBoxStyle = AreaBox.style,
|
||||
color: Color = AreaBoxDefaults.color,
|
||||
style: AreaBoxStyle = AreaBoxDefaults.style,
|
||||
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
|
||||
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
@@ -153,7 +196,10 @@ private fun Modifier.areaBox(
|
||||
.padding(style.padding)
|
||||
}
|
||||
|
||||
object AreaBox {
|
||||
/**
|
||||
* Defaults of area box.
|
||||
*/
|
||||
object AreaBoxDefaults {
|
||||
val color: Color
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
|
@@ -51,17 +51,29 @@ import com.highcapable.betterandroid.compose.extension.ui.orNull
|
||||
import com.highcapable.flexiui.LocalColors
|
||||
import com.highcapable.flexiui.LocalShapes
|
||||
import com.highcapable.flexiui.LocalSizes
|
||||
import com.highcapable.flexiui.interaction.Interaction
|
||||
import com.highcapable.flexiui.interaction.InteractionDefaults
|
||||
import com.highcapable.flexiui.interaction.RippleStyle
|
||||
import com.highcapable.flexiui.interaction.rippleClickable
|
||||
import com.highcapable.flexiui.interaction.rippleToggleable
|
||||
|
||||
/**
|
||||
* Colors defines for button.
|
||||
* @param contentColor the content color, usually for icon tint and text color.
|
||||
* @param backgroundColor the background color.
|
||||
*/
|
||||
@Immutable
|
||||
data class ButtonColors(
|
||||
val contentColor: Color,
|
||||
val backgroundColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for button.
|
||||
* @param rippleStyle the ripple style of this button.
|
||||
* @param padding the padding of content.
|
||||
* @param shape the shape.
|
||||
* @param border the border stroke.
|
||||
*/
|
||||
@Immutable
|
||||
data class ButtonStyle(
|
||||
val rippleStyle: RippleStyle,
|
||||
@@ -70,12 +82,26 @@ data class ButtonStyle(
|
||||
val border: BorderStroke
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI button.
|
||||
* @see IconButton
|
||||
* @see IconToggleButton
|
||||
* @param onClick the callback when button is clicked.
|
||||
* @param modifier the [Modifier] to be applied to this button.
|
||||
* @param colors the colors of this button, default is [ButtonDefaults.colors].
|
||||
* @param style the style of this button, default is [ButtonDefaults.style].
|
||||
* @param enabled whether this button is enabled, default is true.
|
||||
* @param interactionSource the interaction source of this button.
|
||||
* @param header the header content of the [Button], should typically be [Icon] or [Text].
|
||||
* @param footer the footer content of the [Button], should typically be [Icon] or [Text].
|
||||
* @param content the content of the [Button], should typically be [Icon] or [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun Button(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: ButtonColors = Button.colors,
|
||||
style: ButtonStyle = Button.style,
|
||||
colors: ButtonColors = ButtonDefaults.colors,
|
||||
style: ButtonStyle = ButtonDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
header: @Composable () -> Unit = {},
|
||||
@@ -119,12 +145,24 @@ fun Button(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI icon button.
|
||||
* @see IconToggleButton
|
||||
* @see Button
|
||||
* @param onClick the callback when button is clicked.
|
||||
* @param modifier the [Modifier] to be applied to this button.
|
||||
* @param colors the colors of this button, default is [IconButtonDefaults.colors].
|
||||
* @param style the style of this button, default is [IconButtonDefaults.style].
|
||||
* @param enabled whether this button is enabled, default is true.
|
||||
* @param interactionSource the interaction source of this button.
|
||||
* @param content the content of the [IconButton], should typically be [Icon].
|
||||
*/
|
||||
@Composable
|
||||
fun IconButton(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: ButtonColors = IconButton.colors,
|
||||
style: ButtonStyle = IconButton.style,
|
||||
colors: ButtonColors = IconButtonDefaults.colors,
|
||||
style: ButtonStyle = IconButtonDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable () -> Unit
|
||||
@@ -151,13 +189,26 @@ fun IconButton(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI icon toggle button.
|
||||
* @see IconButton
|
||||
* @see Button
|
||||
* @param checked the checked state of this button.
|
||||
* @param onCheckedChange the callback when checked state is changed.
|
||||
* @param modifier the [Modifier] to be applied to this button.
|
||||
* @param colors the colors of this button, default is [IconButtonDefaults.colors].
|
||||
* @param style the style of this button, default is [IconButtonDefaults.style].
|
||||
* @param enabled whether this button is enabled, default is true.
|
||||
* @param interactionSource the interaction source of this button.
|
||||
* @param content the content of the [IconToggleButton], should typically be [Icon].
|
||||
*/
|
||||
@Composable
|
||||
fun IconToggleButton(
|
||||
checked: Boolean,
|
||||
onCheckedChange: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: ButtonColors = IconButton.colors,
|
||||
style: ButtonStyle = IconButton.style,
|
||||
colors: ButtonColors = IconButtonDefaults.colors,
|
||||
style: ButtonStyle = IconButtonDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable () -> Unit
|
||||
@@ -205,7 +256,10 @@ private fun Modifier.button(
|
||||
.then(then)
|
||||
}
|
||||
|
||||
object Button {
|
||||
/**
|
||||
* Defaults of button.
|
||||
*/
|
||||
object ButtonDefaults {
|
||||
val colors: ButtonColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
@@ -216,7 +270,10 @@ object Button {
|
||||
get() = defaultButtonStyle()
|
||||
}
|
||||
|
||||
object IconButton {
|
||||
/**
|
||||
* Defaults of icon button.
|
||||
*/
|
||||
object IconButtonDefaults {
|
||||
val colors: ButtonColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
@@ -246,12 +303,16 @@ private fun defaultContentButtonColors() = ButtonColors(
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultPrimaryButtonRippleStyle() =
|
||||
Interaction.rippleStyle.copy(color = LocalColors.current.foregroundSecondary)
|
||||
InteractionDefaults.rippleStyle.copy(color = LocalColors.current.foregroundSecondary)
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultContentButtonRippleStyle() =
|
||||
Interaction.rippleStyle.copy(color = LocalColors.current.themeSecondary)
|
||||
InteractionDefaults.rippleStyle.copy(color = LocalColors.current.themeSecondary)
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultIconButtonRippleStyle() = InteractionDefaults.rippleStyle.copy(bounded = false)
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
@@ -297,10 +358,6 @@ private fun defaultIconButtonStyle() = ButtonStyle(
|
||||
border = defaultButtonBorder()
|
||||
)
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultIconButtonRippleStyle() = Interaction.rippleStyle.copy(bounded = false)
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultButtonBorder() = BorderStroke(LocalSizes.current.borderSizeTertiary, LocalColors.current.textPrimary)
|
@@ -60,6 +60,12 @@ import com.highcapable.flexiui.LocalSizes
|
||||
import com.highcapable.flexiui.resources.Icons
|
||||
import com.highcapable.flexiui.resources.icon.CheckMark
|
||||
|
||||
/**
|
||||
* Colors defines for check box.
|
||||
* @param contentColor the color of the check mark.
|
||||
* @param inactiveColor the color of the unchecked box.
|
||||
* @param activeColor the color of the checked box.
|
||||
*/
|
||||
@Immutable
|
||||
data class CheckBoxColors(
|
||||
val contentColor: Color,
|
||||
@@ -67,6 +73,16 @@ data class CheckBoxColors(
|
||||
val activeColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for check box.
|
||||
* @param contentSpacing the spacing between the check mark and the content.
|
||||
* @param contentSize the size of the check mark.
|
||||
* @param strokeSize the stroke size.
|
||||
* @param pressedGain the gain when pressed.
|
||||
* @param hoveredGain the gain when hovered.
|
||||
* @param shape the shape.
|
||||
* @param border the border stroke.
|
||||
*/
|
||||
@Immutable
|
||||
data class CheckBoxStyle(
|
||||
val contentSpacing: Dp,
|
||||
@@ -78,13 +94,24 @@ data class CheckBoxStyle(
|
||||
val border: BorderStroke
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI check box.
|
||||
* @param checked the checked state of this check box.
|
||||
* @param onCheckedChange the callback when checked state changed.
|
||||
* @param modifier the [Modifier] to be applied to this check box.
|
||||
* @param colors the colors of this check box, default is [CheckBoxDefaults.colors].
|
||||
* @param style the style of this check box, default is [CheckBoxDefaults.style].
|
||||
* @param enabled whether this check box is enabled, default is true.
|
||||
* @param interactionSource the interaction source of this check box.
|
||||
* @param content the content of the [RowScope] to be applied to the [CheckBox], should typically be [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun CheckBox(
|
||||
checked: Boolean,
|
||||
onCheckedChange: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: CheckBoxColors = CheckBox.colors,
|
||||
style: CheckBoxStyle = CheckBox.style,
|
||||
colors: CheckBoxColors = CheckBoxDefaults.colors,
|
||||
style: CheckBoxStyle = CheckBoxDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable (RowScope.() -> Unit)? = null
|
||||
@@ -119,7 +146,7 @@ fun CheckBox(
|
||||
scaleY = animatedContentLayer
|
||||
),
|
||||
imageVector = Icons.CheckMark,
|
||||
style = Icon.style.copy(tint = colors.contentColor)
|
||||
style = IconDefaults.style.copy(tint = colors.contentColor)
|
||||
)
|
||||
}
|
||||
content?.also { content ->
|
||||
@@ -131,7 +158,10 @@ fun CheckBox(
|
||||
}
|
||||
}
|
||||
|
||||
object CheckBox {
|
||||
/**
|
||||
* Defaults of check box.
|
||||
*/
|
||||
object CheckBoxDefaults {
|
||||
val colors: CheckBoxColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
|
@@ -117,6 +117,14 @@ import com.highcapable.flexiui.resources.icon.Dropdown
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* Colors defines for dropdown list.
|
||||
* @param endIconInactiveTint the tint of the end icon when inactive.
|
||||
* @param endIconActiveTint the tint of the end icon when active.
|
||||
* @param borderInactiveColor the color of the border when inactive.
|
||||
* @param borderActiveColor the color of the border when active.
|
||||
* @param backgroundColor the background color.
|
||||
*/
|
||||
@Immutable
|
||||
data class DropdownListColors(
|
||||
val endIconInactiveTint: Color,
|
||||
@@ -126,6 +134,12 @@ data class DropdownListColors(
|
||||
val backgroundColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Colors defines for dropdown menu.
|
||||
* @param contentColor the color of the content.
|
||||
* @param activeColor the color of the active item.
|
||||
* @param borderColor the color of the border.
|
||||
*/
|
||||
@Immutable
|
||||
data class DropdownMenuColors(
|
||||
val contentColor: Color,
|
||||
@@ -133,6 +147,14 @@ data class DropdownMenuColors(
|
||||
val borderColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for dropdown list.
|
||||
* @param padding the padding of the content.
|
||||
* @param shape the shape.
|
||||
* @param endIconSize the size of the end icon.
|
||||
* @param borderInactive the border stroke when inactive.
|
||||
* @param borderActive the border stroke when active.
|
||||
*/
|
||||
@Immutable
|
||||
data class DropdownListStyle(
|
||||
val padding: ComponentPadding,
|
||||
@@ -142,6 +164,13 @@ data class DropdownListStyle(
|
||||
val borderActive: BorderStroke
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for dropdown menu.
|
||||
* @param inTransitionDuration the duration of the in transition.
|
||||
* @param outTransitionDuration the duration of the out transition.
|
||||
* @param contentStyle the content style of area box.
|
||||
* @param borderStyle the brder style of area box.
|
||||
*/
|
||||
@Immutable
|
||||
data class DropdownMenuStyle(
|
||||
val inTransitionDuration: Int,
|
||||
@@ -150,15 +179,33 @@ data class DropdownMenuStyle(
|
||||
val borderStyle: AreaBoxStyle
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI dropdown list.
|
||||
* @see DropdownMenu
|
||||
* @see DropdownMenuItem
|
||||
* @param expanded whether the dropdown menu is expanded.
|
||||
* @param onExpandedChange the callback when the expanded state is changed.
|
||||
* @param modifier the [Modifier] to be applied to this dropdown list.
|
||||
* @param colors the colors of this dropdown list, default is [DropdownListDefaults.colors].
|
||||
* @param style the style of this dropdown list, default is [DropdownListDefaults.style].
|
||||
* @param menuColors the colors of the dropdown menu, default is [DropdownMenuDefaults.colors].
|
||||
* @param menuStyle the style of the dropdown menu, default is [DropdownMenuDefaults.style].
|
||||
* @param enabled whether the dropdown list is enabled, default is true.
|
||||
* @param scrollState the scroll state of the dropdown menu.
|
||||
* @param properties the popup properties.
|
||||
* @param interactionSource the interaction source of the dropdown list.
|
||||
* @param text the text of the [DropdownList], should typically be [Text].
|
||||
* @param content the content of the [DropdownMenu], should typically be [DropdownMenuItem].
|
||||
*/
|
||||
@Composable
|
||||
fun DropdownList(
|
||||
expanded: Boolean,
|
||||
onExpandedChange: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: DropdownListColors = DropdownList.colors,
|
||||
style: DropdownListStyle = DropdownList.style,
|
||||
menuColors: DropdownMenuColors = DropdownMenu.colors,
|
||||
menuStyle: DropdownMenuStyle = DropdownMenu.style,
|
||||
colors: DropdownListColors = DropdownListDefaults.colors,
|
||||
style: DropdownListStyle = DropdownListDefaults.style,
|
||||
menuColors: DropdownMenuColors = DropdownMenuDefaults.colors,
|
||||
menuStyle: DropdownMenuStyle = DropdownMenuDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
scrollState: ScrollState = rememberScrollState(),
|
||||
properties: PopupProperties = PopupProperties(focusable = true),
|
||||
@@ -218,7 +265,7 @@ fun DropdownList(
|
||||
rotationZ = animatedDirection
|
||||
}.size(style.endIconSize),
|
||||
imageVector = Icons.Dropdown,
|
||||
style = Icon.style.copy(tint = animatedEndIconTint)
|
||||
style = IconDefaults.style.copy(tint = animatedEndIconTint)
|
||||
)
|
||||
}
|
||||
DropdownMenu(
|
||||
@@ -235,13 +282,27 @@ fun DropdownList(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI dropdown menu.
|
||||
* @see DropdownList
|
||||
* @see DropdownMenuItem
|
||||
* @param expanded whether the dropdown menu is expanded.
|
||||
* @param onDismissRequest the callback when the dropdown menu is dismissed.
|
||||
* @param modifier the [Modifier] to be applied to this dropdown menu.
|
||||
* @param colors the colors of this dropdown menu, default is [DropdownMenuDefaults.colors].
|
||||
* @param style the style of this dropdown menu, default is [DropdownMenuDefaults.style].
|
||||
* @param offset the offset of this dropdown menu.
|
||||
* @param scrollState the scroll state of the dropdown menu.
|
||||
* @param properties the popup properties.
|
||||
* @param content the content of the [DropdownMenu], should typically be [DropdownMenuItem].
|
||||
*/
|
||||
@Composable
|
||||
fun DropdownMenu(
|
||||
expanded: Boolean,
|
||||
onDismissRequest: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: DropdownMenuColors = DropdownMenu.colors,
|
||||
style: DropdownMenuStyle = DropdownMenu.style,
|
||||
colors: DropdownMenuColors = DropdownMenuDefaults.colors,
|
||||
style: DropdownMenuStyle = DropdownMenuDefaults.style,
|
||||
offset: DpOffset = DpOffset(0.dp, 0.dp),
|
||||
scrollState: ScrollState = rememberScrollState(),
|
||||
properties: PopupProperties = PopupProperties(focusable = true),
|
||||
@@ -278,6 +339,13 @@ fun DropdownMenu(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A box for manually measuring the size of the dropdown menu.
|
||||
* @see DropdownList
|
||||
* @see DropdownMenu
|
||||
* @param modifier the [Modifier] to be applied to this box.
|
||||
* @param content the content for measuring.
|
||||
*/
|
||||
@Composable
|
||||
fun DropdownMenuBox(
|
||||
modifier: Modifier = Modifier,
|
||||
@@ -307,6 +375,20 @@ fun DropdownMenuBox(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI dropdown menu item.
|
||||
* @see DropdownList
|
||||
* @see DropdownMenu
|
||||
* @param onClick the callback when the dropdown menu item is clicked.
|
||||
* @param modifier the [Modifier] to be applied to this dropdown menu item.
|
||||
* @param contentColor the color of the content.
|
||||
* @param activeColor the color of the active item.
|
||||
* @param contentStyle the style of the content.
|
||||
* @param enabled whether the dropdown menu item is enabled, default is true.
|
||||
* @param actived whether the dropdown menu item is actived, default is false.
|
||||
* @param interactionSource the interaction source of the dropdown menu item.
|
||||
* @param content the content of the [DropdownMenuItem], should typically be [Icon] or [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun DropdownMenuItem(
|
||||
onClick: () -> Unit,
|
||||
@@ -319,9 +401,15 @@ fun DropdownMenuItem(
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
val currentColor = contentColor.orNull() ?: LocalDropdownMenuContentColor.current.orNull() ?: DropdownMenu.colors.contentColor
|
||||
val currentActiveColor = activeColor.orNull() ?: LocalDropdownMenuActiveColor.current.orNull() ?: DropdownMenu.colors.activeColor
|
||||
val currentStyle = contentStyle ?: LocalDropdownMenuContentStyle.current ?: DropdownMenu.style.contentStyle
|
||||
val currentColor = contentColor.orNull()
|
||||
?: LocalDropdownMenuContentColor.current.orNull()
|
||||
?: DropdownMenuDefaults.colors.contentColor
|
||||
val currentActiveColor = activeColor.orNull()
|
||||
?: LocalDropdownMenuActiveColor.current.orNull()
|
||||
?: DropdownMenuDefaults.colors.activeColor
|
||||
val currentStyle = contentStyle
|
||||
?: LocalDropdownMenuContentStyle.current
|
||||
?: DropdownMenuDefaults.style.contentStyle
|
||||
AreaRow(
|
||||
modifier = Modifier.componentState(enabled)
|
||||
.then(modifier)
|
||||
@@ -354,6 +442,9 @@ internal expect fun DropdownMenuMeasureBox(
|
||||
content: @Composable BoxScope.() -> Unit
|
||||
)
|
||||
|
||||
/**
|
||||
* A scope for dropdown menu box.
|
||||
*/
|
||||
@Stable
|
||||
interface DropdownMenuBoxScope : BoxWithConstraintsScope {
|
||||
val menuMaxHeight: Dp
|
||||
@@ -516,7 +607,10 @@ private data class DropdownMenuPositionProvider(
|
||||
}
|
||||
}
|
||||
|
||||
object DropdownList {
|
||||
/**
|
||||
* Defaults of dropdown list.
|
||||
*/
|
||||
object DropdownListDefaults {
|
||||
val colors: DropdownListColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
@@ -527,7 +621,10 @@ object DropdownList {
|
||||
get() = defaultDropdownListStyle()
|
||||
}
|
||||
|
||||
object DropdownMenu {
|
||||
/**
|
||||
* Defaults of dropdown menu.
|
||||
*/
|
||||
object DropdownMenuDefaults {
|
||||
val colors: DropdownMenuColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
@@ -577,11 +674,11 @@ private fun defaultDropdownListStyle() = DropdownListStyle(
|
||||
private fun defaultDropdownMenuStyle() = DropdownMenuStyle(
|
||||
inTransitionDuration = DefaultInTransitionDuration,
|
||||
outTransitionDuration = DefaultOutTransitionDuration,
|
||||
contentStyle = AreaBox.style.copy(
|
||||
contentStyle = AreaBoxDefaults.style.copy(
|
||||
padding = ComponentPadding(horizontal = DefaultMenuContentPadding),
|
||||
shape = LocalShapes.current.secondary
|
||||
),
|
||||
borderStyle = AreaBox.style.copy(
|
||||
borderStyle = AreaBoxDefaults.style.copy(
|
||||
padding = ComponentPadding(LocalSizes.current.spacingTertiary),
|
||||
shadowSize = LocalSizes.current.zoomSizeTertiary,
|
||||
shape = LocalShapes.current.primary
|
||||
|
@@ -51,31 +51,49 @@ import androidx.compose.ui.unit.isSpecified
|
||||
import com.highcapable.betterandroid.compose.extension.ui.orNull
|
||||
import com.highcapable.flexiui.LocalSizes
|
||||
|
||||
/**
|
||||
* Style defines for icon.
|
||||
* @param size the size.
|
||||
* @param tint the tint.
|
||||
*/
|
||||
@Immutable
|
||||
data class IconStyle(
|
||||
val size: Dp,
|
||||
val tint: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI basic icon.
|
||||
* @param imageVector the vector image to be drawn.
|
||||
* @param contentDescription the content description for this icon.
|
||||
* @param modifier the [Modifier] to be applied to this icon.
|
||||
* @param style the style of this icon, default is [IconDefaults.style].
|
||||
*/
|
||||
@Composable
|
||||
fun Icon(
|
||||
imageVector: ImageVector,
|
||||
contentDescription: String? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
style: IconStyle = Icon.style
|
||||
style: IconStyle = IconDefaults.style
|
||||
) {
|
||||
val painter = rememberVectorPainter(imageVector)
|
||||
Icon(painter, contentDescription, modifier, style)
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI basic icon.
|
||||
* @param painter the painter to be drawn.
|
||||
* @param contentDescription the content description for this icon.
|
||||
* @param modifier the [Modifier] to be applied to this icon.
|
||||
* @param style the style of this icon, default is [IconDefaults.style].
|
||||
*/
|
||||
@Composable
|
||||
fun Icon(
|
||||
painter: Painter,
|
||||
contentDescription: String? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
style: IconStyle = Icon.style
|
||||
style: IconStyle = IconDefaults.style
|
||||
) {
|
||||
// TODO: b/149735981 semantics for content description
|
||||
val colorFilter = if (style.tint.isUnspecified) null else ColorFilter.tint(style.tint)
|
||||
val semantics = if (contentDescription != null)
|
||||
Modifier.semantics {
|
||||
@@ -114,7 +132,10 @@ private fun Modifier.defaultSizeFor(
|
||||
})
|
||||
}
|
||||
|
||||
object Icon {
|
||||
/**
|
||||
* Defaults of icon.
|
||||
*/
|
||||
object IconDefaults {
|
||||
val style: IconStyle
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
package com.highcapable.flexiui.component
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -47,6 +48,13 @@ import com.highcapable.flexiui.interaction.rippleClickable
|
||||
import com.highcapable.flexiui.resources.Icons
|
||||
import com.highcapable.flexiui.resources.icon.ArrowForward
|
||||
|
||||
/**
|
||||
* Colors defines for item box.
|
||||
* @param backgroundColor the background color.
|
||||
* @param titleTextColor the title text color.
|
||||
* @param subTextColor the sub text color.
|
||||
* @param arrowIconTint the arrow icon tint.
|
||||
*/
|
||||
@Immutable
|
||||
data class ItemBoxColors(
|
||||
val backgroundColor: Color,
|
||||
@@ -55,6 +63,13 @@ data class ItemBoxColors(
|
||||
val arrowIconTint: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for item box.
|
||||
* @param boxStyle the style of area box.
|
||||
* @param contentSpacing the spacing between the components of content.
|
||||
* @param titleTextStyle the title text style.
|
||||
* @param subTextStyle the sub text style.
|
||||
*/
|
||||
@Immutable
|
||||
data class ItemBoxStyle(
|
||||
val boxStyle: AreaBoxStyle,
|
||||
@@ -63,12 +78,26 @@ data class ItemBoxStyle(
|
||||
val subTextStyle: TextStyle
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI horizontal item box.
|
||||
* @see VerticalItemBox
|
||||
* @param onClick the callback when item is clicked.
|
||||
* @param modifier the [Modifier] to be applied to this item box.
|
||||
* @param colors the colors of item box, default is [ItemBoxDefaults.colors].
|
||||
* @param style the style of item box, default is [ItemBoxDefaults.style].
|
||||
* @param enabled whether this item box is enabled, default is true.
|
||||
* @param showArrowIcon whether show arrow icon, default is true.
|
||||
* @param interactionSource the interaction source of this item box.
|
||||
* @param logoImage the logo image of the [HorizontalItemBox], should typically be [Icon] or [Image].
|
||||
* @param titleText the title text of the [HorizontalItemBox], should typically be [Text].
|
||||
* @param subText the sub text of the [HorizontalItemBox], should typically be [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun HorizontalItemBox(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: ItemBoxColors = ItemBox.colors,
|
||||
style: ItemBoxStyle = ItemBox.style,
|
||||
colors: ItemBoxColors = ItemBoxDefaults.colors,
|
||||
style: ItemBoxStyle = ItemBoxDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
showArrowIcon: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
@@ -105,7 +134,7 @@ fun HorizontalItemBox(
|
||||
}
|
||||
if (showArrowIcon) Icon(
|
||||
imageVector = Icons.ArrowForward,
|
||||
style = Icon.style.copy(
|
||||
style = IconDefaults.style.copy(
|
||||
size = DefaultArrowIconSize,
|
||||
tint = colors.arrowIconTint
|
||||
)
|
||||
@@ -114,12 +143,25 @@ fun HorizontalItemBox(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI vertical item box.
|
||||
* @see HorizontalItemBox
|
||||
* @param onClick the callback when item is clicked.
|
||||
* @param modifier the [Modifier] to be applied to this item box.
|
||||
* @param colors the colors of item box, default is [ItemBoxDefaults.colors].
|
||||
* @param style the style of item box, default is [ItemBoxDefaults.style].
|
||||
* @param enabled whether this item box is enabled, default is true.
|
||||
* @param interactionSource the interaction source of this item box.
|
||||
* @param logoImage the logo image of the [VerticalItemBox], should typically be [Icon] or [Image].
|
||||
* @param titleText the title text of the [VerticalItemBox], should typically be [Text].
|
||||
* @param subText the sub text of the [VerticalItemBox], should typically be [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun VerticalItemBox(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: ItemBoxColors = ItemBox.colors,
|
||||
style: ItemBoxStyle = ItemBox.style,
|
||||
colors: ItemBoxColors = ItemBoxDefaults.colors,
|
||||
style: ItemBoxStyle = ItemBoxDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
logoImage: @Composable (() -> Unit)? = null,
|
||||
@@ -167,7 +209,10 @@ private fun ItemBoxContent(
|
||||
}
|
||||
}
|
||||
|
||||
object ItemBox {
|
||||
/**
|
||||
* Defaults of item box.
|
||||
*/
|
||||
object ItemBoxDefaults {
|
||||
val colors: ItemBoxColors
|
||||
@Composable
|
||||
get() = defaultItemBoxColors()
|
||||
@@ -179,7 +224,7 @@ object ItemBox {
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultItemBoxColors() = ItemBoxColors(
|
||||
backgroundColor = AreaBox.color,
|
||||
backgroundColor = AreaBoxDefaults.color,
|
||||
titleTextColor = LocalColors.current.textPrimary,
|
||||
subTextColor = LocalColors.current.textSecondary,
|
||||
arrowIconTint = LocalColors.current.textSecondary
|
||||
@@ -188,7 +233,7 @@ private fun defaultItemBoxColors() = ItemBoxColors(
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultItemBoxStyle() = ItemBoxStyle(
|
||||
boxStyle = AreaBox.style,
|
||||
boxStyle = AreaBoxDefaults.style,
|
||||
contentSpacing = LocalSizes.current.spacingSecondary,
|
||||
titleTextStyle = LocalTypography.current.primary,
|
||||
subTextStyle = LocalTypography.current.secondary
|
||||
|
@@ -60,9 +60,16 @@ import com.highcapable.betterandroid.compose.extension.ui.componentState
|
||||
import com.highcapable.betterandroid.compose.extension.ui.orNull
|
||||
import com.highcapable.flexiui.LocalColors
|
||||
import com.highcapable.flexiui.LocalSizes
|
||||
import com.highcapable.flexiui.interaction.Interaction
|
||||
import com.highcapable.flexiui.interaction.InteractionDefaults
|
||||
import com.highcapable.flexiui.interaction.rippleClickable
|
||||
|
||||
/**
|
||||
* Colors defines for navigation bar.
|
||||
* @param backgroundColor the background color.
|
||||
* @param indicatorColor the indicator color.
|
||||
* @param selectedContentColor the selected content color.
|
||||
* @param unselectedContentColor the unselected content color.
|
||||
*/
|
||||
@Immutable
|
||||
data class NavigationBarColors(
|
||||
val backgroundColor: Color,
|
||||
@@ -71,6 +78,13 @@ data class NavigationBarColors(
|
||||
val unselectedContentColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for navigation bar.
|
||||
* @param boxStyle the style of area box.
|
||||
* @param contentSpacing the spacing between the components of content.
|
||||
* @param contentPadding the padding of content.
|
||||
* @param contentShape the content shape.
|
||||
*/
|
||||
@Immutable
|
||||
data class NavigationBarStyle(
|
||||
val boxStyle: AreaBoxStyle,
|
||||
@@ -79,11 +93,21 @@ data class NavigationBarStyle(
|
||||
val contentShape: Shape
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI horizontal navigation bar.
|
||||
* @see NavigationBarColumn
|
||||
* @see NavigationBarItem
|
||||
* @param modifier the [Modifier] to be applied to this navigation bar.
|
||||
* @param colors the colors of this navigation bar, default is [NavigationBarDefaults.colors].
|
||||
* @param style the style of this navigation bar, default is [NavigationBarDefaults.style].
|
||||
* @param arrangement the horizontal arrangement of this navigation bar, default is [Arrangement.SpaceBetween].
|
||||
* @param content the content of the [NavigationBarRow], should typically be [NavigationBarItem].
|
||||
*/
|
||||
@Composable
|
||||
fun NavigationRow(
|
||||
fun NavigationBarRow(
|
||||
modifier: Modifier = Modifier,
|
||||
colors: NavigationBarColors = NavigationBar.colors,
|
||||
style: NavigationBarStyle = NavigationBar.style,
|
||||
colors: NavigationBarColors = NavigationBarDefaults.colors,
|
||||
style: NavigationBarStyle = NavigationBarDefaults.style,
|
||||
arrangement: Arrangement.Horizontal = Arrangement.SpaceBetween,
|
||||
content: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
@@ -99,11 +123,21 @@ fun NavigationRow(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI vertical navigation bar.
|
||||
* @see NavigationBarRow
|
||||
* @see NavigationBarItem
|
||||
* @param modifier the [Modifier] to be applied to this navigation bar.
|
||||
* @param colors the colors of this navigation bar, default is [NavigationBarDefaults.colors].
|
||||
* @param style the style of this navigation bar, default is [NavigationBarDefaults.style].
|
||||
* @param arrangement the vertical arrangement of this navigation bar, default is [Arrangement.SpaceBetween].
|
||||
* @param content the content of the [NavigationBarColumn], should typically be [NavigationBarItem].
|
||||
*/
|
||||
@Composable
|
||||
fun NavigationColumn(
|
||||
fun NavigationBarColumn(
|
||||
modifier: Modifier = Modifier,
|
||||
colors: NavigationBarColors = NavigationBar.colors,
|
||||
style: NavigationBarStyle = NavigationBar.style,
|
||||
colors: NavigationBarColors = NavigationBarDefaults.colors,
|
||||
style: NavigationBarStyle = NavigationBarDefaults.style,
|
||||
arrangement: Arrangement.Vertical = Arrangement.SpaceBetween,
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
) {
|
||||
@@ -119,6 +153,23 @@ fun NavigationColumn(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI navigation bar item.
|
||||
* @see NavigationBarRow
|
||||
* @see NavigationBarColumn
|
||||
* @param selected whether this item is selected.
|
||||
* @param onClick the callback when item is clicked.
|
||||
* @param horizontal whether this item is horizontal.
|
||||
* @param modifier the [Modifier] to be applied to this item.
|
||||
* @param enabled whether this item is enabled, default is true.
|
||||
* @param colors the colors of this item.
|
||||
* @param contentSpacing the spacing between the components of content of this item.
|
||||
* @param contentPadding the padding of content of this item.
|
||||
* @param contentShape the content shape of this item.
|
||||
* @param interactionSource the interaction source of this item.
|
||||
* @param icon the icon of the [NavigationBarItem], should typically be [Icon].
|
||||
* @param text the text of the [NavigationBarItem], should typically be [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun NavigationBarItem(
|
||||
selected: Boolean,
|
||||
@@ -135,10 +186,16 @@ fun NavigationBarItem(
|
||||
text: @Composable (() -> Unit)? = null
|
||||
) {
|
||||
val currentHorizontal = horizontal ?: LocalHorizontalNavigationBar.current
|
||||
val currentColors = colors ?: LocalNavigationBarColors.current ?: NavigationBar.colors
|
||||
val currentContentSpacing = contentSpacing.orNull() ?: LocalNavigationBarContentSpacing.current.orNull() ?: NavigationBar.style.contentSpacing
|
||||
val currentContentPadding = contentPadding ?: LocalNavigationBarContentPadding.current ?: NavigationBar.style.contentPadding
|
||||
val currentContentShape = contentShape ?: LocalNavigationBarContentShape.current ?: NavigationBar.style.contentShape
|
||||
val currentColors = colors ?: LocalNavigationBarColors.current ?: NavigationBarDefaults.colors
|
||||
val currentContentSpacing = contentSpacing.orNull()
|
||||
?: LocalNavigationBarContentSpacing.current.orNull()
|
||||
?: NavigationBarDefaults.style.contentSpacing
|
||||
val currentContentPadding = contentPadding
|
||||
?: LocalNavigationBarContentPadding.current
|
||||
?: NavigationBarDefaults.style.contentPadding
|
||||
val currentContentShape = contentShape
|
||||
?: LocalNavigationBarContentShape.current
|
||||
?: NavigationBarDefaults.style.contentShape
|
||||
val animatedIndicatorColor by animateColorAsState(if (selected) currentColors.indicatorColor else Color.Transparent)
|
||||
val animatedContentColor by animateColorAsState(if (selected) currentColors.selectedContentColor else currentColors.unselectedContentColor)
|
||||
val currentIconStyle = LocalIconStyle.current.copy(tint = animatedContentColor)
|
||||
@@ -149,7 +206,7 @@ fun NavigationBarItem(
|
||||
.then(modifier)
|
||||
.background(animatedIndicatorColor)
|
||||
.rippleClickable(
|
||||
rippleStyle = Interaction.rippleStyle.copy(color = currentColors.indicatorColor),
|
||||
rippleStyle = InteractionDefaults.rippleStyle.copy(color = currentColors.indicatorColor),
|
||||
enabled = enabled,
|
||||
role = Role.Tab,
|
||||
interactionSource = interactionSource,
|
||||
@@ -214,7 +271,10 @@ private fun NavigationBarStyleBox(
|
||||
}
|
||||
}
|
||||
|
||||
object NavigationBar {
|
||||
/**
|
||||
* Defaults of navigation bar.
|
||||
*/
|
||||
object NavigationBarDefaults {
|
||||
val colors: NavigationBarColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
@@ -238,7 +298,7 @@ private val LocalNavigationBarContentShape = compositionLocalOf<Shape?> { null }
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultNavigationBarColors() = NavigationBarColors(
|
||||
backgroundColor = AreaBox.color,
|
||||
backgroundColor = AreaBoxDefaults.color,
|
||||
indicatorColor = LocalColors.current.themeTertiary,
|
||||
selectedContentColor = LocalColors.current.themePrimary,
|
||||
unselectedContentColor = LocalColors.current.textSecondary
|
||||
@@ -247,7 +307,7 @@ private fun defaultNavigationBarColors() = NavigationBarColors(
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultNavigationBarStyle() = NavigationBarStyle(
|
||||
boxStyle = AreaBox.style,
|
||||
boxStyle = AreaBoxDefaults.style,
|
||||
contentSpacing = LocalSizes.current.spacingSecondary,
|
||||
contentPadding = ComponentPadding(
|
||||
horizontal = LocalSizes.current.spacingPrimary,
|
||||
|
@@ -58,17 +58,30 @@ import kotlin.math.PI
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* Style interface for progress indicator.
|
||||
*/
|
||||
@Stable
|
||||
interface ProgressIndicatorStyle {
|
||||
val strokeWidth: Dp
|
||||
val strokeCap: StrokeCap
|
||||
}
|
||||
|
||||
/**
|
||||
* Animation interface for progress indicator.
|
||||
*/
|
||||
@Stable
|
||||
interface ProgressIndicatorAnimation {
|
||||
val duration: Int
|
||||
}
|
||||
|
||||
/**
|
||||
* Style defines for circular progress indicator.
|
||||
* @param strokeWidth the stroke width of indicator.
|
||||
* @param strokeCap the stroke cap of indicator.
|
||||
* @param radius the radius of indicator.
|
||||
* @param animation the animation of indicator.
|
||||
*/
|
||||
@Immutable
|
||||
data class CircularIndicatorStyle(
|
||||
override val strokeWidth: Dp,
|
||||
@@ -77,6 +90,13 @@ data class CircularIndicatorStyle(
|
||||
val animation: CircularIndicatorAnimation
|
||||
) : ProgressIndicatorStyle
|
||||
|
||||
/**
|
||||
* Style defines for linear progress indicator.
|
||||
* @param strokeWidth the stroke width of indicator.
|
||||
* @param strokeCap the stroke cap of indicator.
|
||||
* @param width the width of indicator.
|
||||
* @param animation the animation of indicator.
|
||||
*/
|
||||
@Immutable
|
||||
data class LinearIndicatorStyle(
|
||||
override val strokeWidth: Dp,
|
||||
@@ -85,6 +105,14 @@ data class LinearIndicatorStyle(
|
||||
val animation: LinearIndicatorAnimation
|
||||
) : ProgressIndicatorStyle
|
||||
|
||||
/**
|
||||
* Animation defines for circular progress indicator.
|
||||
* @param duration the duration of animation.
|
||||
* @param rotationsPerCycle the rotations per cycle of animation.
|
||||
* @param startAngleOffset the start angle offset of animation.
|
||||
* @param baseRotationAngle the base rotation angle of animation.
|
||||
* @param jumpRotationAngle the jump rotation angle of animation.
|
||||
*/
|
||||
@Immutable
|
||||
data class CircularIndicatorAnimation(
|
||||
override val duration: Int,
|
||||
@@ -94,6 +122,18 @@ data class CircularIndicatorAnimation(
|
||||
val jumpRotationAngle: Float
|
||||
) : ProgressIndicatorAnimation
|
||||
|
||||
/**
|
||||
* Animation defines for linear progress indicator.
|
||||
* @param duration the duration of animation.
|
||||
* @param firstLineHeadDuration the first line head duration of animation.
|
||||
* @param firstLineTailDuration the first line tail duration of animation.
|
||||
* @param secondLineHeadDuration the second line head duration of animation.
|
||||
* @param secondLineTailDuration the second line tail duration of animation.
|
||||
* @param firstLineHeadDelay the first line head delay of animation.
|
||||
* @param firstLineTailDelay the first line tail delay of animation.
|
||||
* @param secondLineHeadDelay the second line head delay of animation.
|
||||
* @param secondLineTailDelay the second line tail delay of animation.
|
||||
*/
|
||||
@Immutable
|
||||
data class LinearIndicatorAnimation(
|
||||
override val duration: Int,
|
||||
@@ -107,25 +147,42 @@ data class LinearIndicatorAnimation(
|
||||
val secondLineTailDelay: Int
|
||||
) : ProgressIndicatorAnimation
|
||||
|
||||
/**
|
||||
* Colors defines for progress indicator.
|
||||
* @param foregroundColor the foreground color of indicator.
|
||||
* @param backgroundColor the background color of indicator.
|
||||
*/
|
||||
@Immutable
|
||||
data class ProgressIndicatorColors(
|
||||
val foregroundColor: Color,
|
||||
val backgroundColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI circular progress indicator.
|
||||
* @see LinearProgressIndicator
|
||||
* @param modifier the [Modifier] to be applied to this indicator.
|
||||
* @param progress the progress of indicator.
|
||||
* @param min the min of indicator, default is 0f.
|
||||
* @param max the max of indicator, default is 1f.
|
||||
* @param indeterminate the indeterminate of indicator, default is false.
|
||||
* @param colors the colors of indicator, default is [CircularIndicatorDefaults.colors].
|
||||
* @param style the style of indicator, default is [CircularIndicatorDefaults.style].
|
||||
*/
|
||||
@Composable
|
||||
fun CircularProgressIndicator(
|
||||
modifier: Modifier = Modifier,
|
||||
progress: Float = -1f,
|
||||
min: Float = 0f,
|
||||
max: Float = 100f,
|
||||
max: Float = 1f,
|
||||
indeterminate: Boolean = progress < min,
|
||||
colors: ProgressIndicatorColors = CircularProgressIndicator.colors,
|
||||
style: CircularIndicatorStyle = CircularProgressIndicator.style
|
||||
colors: ProgressIndicatorColors = CircularIndicatorDefaults.colors,
|
||||
style: CircularIndicatorStyle = CircularIndicatorDefaults.style
|
||||
) {
|
||||
val diameter = style.radius * 2
|
||||
val stroke = with(LocalDensity.current) { Stroke(width = style.strokeWidth.toPx(), cap = style.strokeCap) }
|
||||
|
||||
/** Build determinate progress indicator. */
|
||||
@Composable
|
||||
fun Determinate() {
|
||||
val coercedProgress = progress.coerceIn(min, max)
|
||||
@@ -138,6 +195,7 @@ fun CircularProgressIndicator(
|
||||
}
|
||||
}
|
||||
|
||||
/** Build indeterminate progress indicator. */
|
||||
@Composable
|
||||
fun Indeterminate() {
|
||||
val transition = rememberInfiniteTransition()
|
||||
@@ -197,16 +255,28 @@ fun CircularProgressIndicator(
|
||||
if (indeterminate) Indeterminate() else Determinate()
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI linear progress indicator.
|
||||
* @see CircularProgressIndicator
|
||||
* @param modifier the [Modifier] to be applied to this indicator.
|
||||
* @param progress the progress of indicator.
|
||||
* @param min the min of indicator, default is 0f.
|
||||
* @param max the max of indicator, default is 1f.
|
||||
* @param indeterminate the indeterminate of indicator, default is false.
|
||||
* @param colors the colors of indicator, default is [LinearIndicatorDefaults.colors].
|
||||
* @param style the style of indicator, default is [LinearIndicatorDefaults.style].
|
||||
*/
|
||||
@Composable
|
||||
fun LinearProgressIndicator(
|
||||
modifier: Modifier = Modifier,
|
||||
progress: Float = -1f,
|
||||
min: Float = 0f,
|
||||
max: Float = 100f,
|
||||
max: Float = 1f,
|
||||
indeterminate: Boolean = progress < min,
|
||||
colors: ProgressIndicatorColors = LinearProgressIndicator.colors,
|
||||
style: LinearIndicatorStyle = LinearProgressIndicator.style
|
||||
colors: ProgressIndicatorColors = LinearIndicatorDefaults.colors,
|
||||
style: LinearIndicatorStyle = LinearIndicatorDefaults.style
|
||||
) {
|
||||
/** Build determinate progress indicator. */
|
||||
@Composable
|
||||
fun Determinate() {
|
||||
val coercedProgress = progress.coerceIn(min, max)
|
||||
@@ -218,6 +288,7 @@ fun LinearProgressIndicator(
|
||||
}
|
||||
}
|
||||
|
||||
/** Build indeterminate progress indicator. */
|
||||
@Composable
|
||||
fun Indeterminate() {
|
||||
val infiniteTransition = rememberInfiniteTransition()
|
||||
@@ -347,7 +418,10 @@ private fun DrawScope.drawLinearIndicator(
|
||||
}
|
||||
}
|
||||
|
||||
object CircularProgressIndicator {
|
||||
/**
|
||||
* Defaults of circular progress indicator.
|
||||
*/
|
||||
object CircularIndicatorDefaults {
|
||||
val colors: ProgressIndicatorColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
@@ -363,7 +437,10 @@ object CircularProgressIndicator {
|
||||
get() = defaultCircularIndicatorStyle()
|
||||
}
|
||||
|
||||
object LinearProgressIndicator {
|
||||
/**
|
||||
* Defaults of linear progress indicator.
|
||||
*/
|
||||
object LinearIndicatorDefaults {
|
||||
val colors: ProgressIndicatorColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
|
@@ -58,6 +58,12 @@ import com.highcapable.flexiui.LocalColors
|
||||
import com.highcapable.flexiui.LocalShapes
|
||||
import com.highcapable.flexiui.LocalSizes
|
||||
|
||||
/**
|
||||
* Colors defines for radio button.
|
||||
* @param contentColor the color of the check mark.
|
||||
* @param inactiveColor the color of the unchecked box.
|
||||
* @param activeColor the color of the checked box.
|
||||
*/
|
||||
@Immutable
|
||||
data class RadioButtonColors(
|
||||
val contentColor: Color,
|
||||
@@ -65,6 +71,16 @@ data class RadioButtonColors(
|
||||
val activeColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for radio button.
|
||||
* @param contentSpacing the spacing between the check mark and the content.
|
||||
* @param contentRadius the radius of the check mark.
|
||||
* @param strokeRadius the radius of the box.
|
||||
* @param pressedGain the gain when pressed.
|
||||
* @param hoveredGain the gain when hovered.
|
||||
* @param shape the shape.
|
||||
* @param border the border stroke.
|
||||
*/
|
||||
@Immutable
|
||||
data class RadioButtonStyle(
|
||||
val contentSpacing: Dp,
|
||||
@@ -77,13 +93,24 @@ data class RadioButtonStyle(
|
||||
val border: BorderStroke
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI radio button.
|
||||
* @param selected the selected state of this button.
|
||||
* @param onClick the callback when button is clicked.
|
||||
* @param modifier the [Modifier] to be applied to this button.
|
||||
* @param colors the colors of this button, default is [RadioButtonDefaults.colors].
|
||||
* @param style the style of this button, default is [RadioButtonDefaults.style].
|
||||
* @param enabled whether this button is enabled, default is true.
|
||||
* @param interactionSource the interaction source of this button.
|
||||
* @param content the content of the [RowScope] to be applied to the [RadioButton], should typically be [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun RadioButton(
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: RadioButtonColors = RadioButton.colors,
|
||||
style: RadioButtonStyle = RadioButton.style,
|
||||
colors: RadioButtonColors = RadioButtonDefaults.colors,
|
||||
style: RadioButtonStyle = RadioButtonDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable (RowScope.() -> Unit)? = null
|
||||
@@ -126,7 +153,10 @@ fun RadioButton(
|
||||
}
|
||||
}
|
||||
|
||||
object RadioButton {
|
||||
/**
|
||||
* Defaults of radio button.
|
||||
*/
|
||||
object RadioButtonDefaults {
|
||||
val colors: RadioButtonColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
|
@@ -34,19 +34,42 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.highcapable.betterandroid.compose.extension.ui.ComponentPadding
|
||||
|
||||
// TODO: re-made it by SubcomposeLayout.
|
||||
|
||||
/**
|
||||
* Scaffold implements the basic Flexi UI visual layout structure.
|
||||
*
|
||||
* You can add your own components into [actionBar], [tab], [navigationBar].
|
||||
* @see TopActionBar
|
||||
* @see ActionBar
|
||||
* @see TabRow
|
||||
* @see NavigationBarRow
|
||||
* @see NavigationBarColumn
|
||||
* @param modifier the [Modifier] to be applied to content.
|
||||
* @param colors the colors of content, default is [SurfaceDefaults.colors].
|
||||
* @param padding the padding of content, default is [SurfaceDefaults.padding].
|
||||
* @param verticalArrangement the vertical arrangement of content, default is [Arrangement.Top].
|
||||
* @param horizontalAlignment the horizontal alignment of content, default is [Alignment.Start].
|
||||
* @param actionBar the action bar, should typically be [TopActionBar] or [ActionBar].
|
||||
* @param tab the tab, should typically be [TabRow].
|
||||
* @param navigationBar the navigation bar, should typically be [NavigationBarRow] or [NavigationBarColumn].
|
||||
* @param content the content of the screen.
|
||||
*/
|
||||
@Composable
|
||||
fun Scaffold(
|
||||
modifier: Modifier = Modifier,
|
||||
colors: SurfaceColors = Surface.colors,
|
||||
padding: ComponentPadding = Surface.padding,
|
||||
colors: SurfaceColors = SurfaceDefaults.colors,
|
||||
padding: ComponentPadding = SurfaceDefaults.padding,
|
||||
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
|
||||
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
|
||||
actionBar: @Composable () -> Unit = {},
|
||||
tab: @Composable () -> Unit = {},
|
||||
navigation: @Composable () -> Unit = {},
|
||||
navigationBar: @Composable () -> Unit = {},
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
// When out of the box, we no need to match the top padding, it should be provided by the action bar.
|
||||
val outBoxPadding = padding.copy(top = 0.dp)
|
||||
// When in the box, we no need to match the start and end padding, it should be provided by the surface.
|
||||
val inBoxPadding = padding.copy(start = 0.dp, end = 0.dp)
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
@@ -60,7 +83,7 @@ fun Scaffold(
|
||||
actionBar()
|
||||
tab()
|
||||
Box(modifier = Modifier.fillMaxSize().padding(inBoxPadding).weight(1f)) { content() }
|
||||
navigation()
|
||||
navigationBar()
|
||||
}
|
||||
}
|
||||
}
|
@@ -69,6 +69,13 @@ import com.highcapable.flexiui.LocalSizes
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* Colors defines for slider.
|
||||
* @param trackInactiveColor the inactive color of track.
|
||||
* @param trackActiveColor the active color of track.
|
||||
* @param thumbColor the color of thumb.
|
||||
* @param stepColor the color of step.
|
||||
*/
|
||||
@Immutable
|
||||
data class SliderColors(
|
||||
val trackInactiveColor: Color,
|
||||
@@ -77,6 +84,20 @@ data class SliderColors(
|
||||
val stepColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for slider.
|
||||
* @param thumbRadius the radius of thumb.
|
||||
* @param thumbGain the gain of thumb.
|
||||
* @param thumbShadowSize the shadow size of thumb.
|
||||
* @param thumbShape the shape of thumb.
|
||||
* @param stepShape the shape of step.
|
||||
* @param trackShape the shape of track.
|
||||
* @param thumbBorder the border of thumb.
|
||||
* @param stepBorder the border of step.
|
||||
* @param trackBorder the border of track.
|
||||
* @param trackWidth the width of track.
|
||||
* @param trackHeight the height of track.
|
||||
*/
|
||||
@Immutable
|
||||
data class SliderStyle(
|
||||
val thumbRadius: Dp,
|
||||
@@ -92,16 +113,30 @@ data class SliderStyle(
|
||||
val trackHeight: Dp
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI slider.
|
||||
* @param value the value of this slider.
|
||||
* @param onValueChange the callback when the value changed.
|
||||
* @param modifier the [Modifier] to be applied to this slider.
|
||||
* @param colors the colors of this slider, default is [SliderDefaults.colors].
|
||||
* @param style the style of this slider, default is [SliderDefaults.style].
|
||||
* @param enabled whether this slider is enabled, default is true.
|
||||
* @param min the min value of this slider, default is 0f.
|
||||
* @param max the max value of this slider, default is 1f.
|
||||
* @param steps the steps of this slider, default is 0.
|
||||
* @param onValueChangeFinished the callback when the value changed finished.
|
||||
* @param interactionSource the interaction source of this slider.
|
||||
*/
|
||||
@Composable
|
||||
fun Slider(
|
||||
value: Float,
|
||||
onValueChange: (Float) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: SliderColors = Slider.colors,
|
||||
style: SliderStyle = Slider.style,
|
||||
colors: SliderColors = SliderDefaults.colors,
|
||||
style: SliderStyle = SliderDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
min: Float = 0f,
|
||||
max: Float = 100f,
|
||||
max: Float = 1f,
|
||||
steps: Int = 0,
|
||||
onValueChangeFinished: (() -> Unit)? = null,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
|
||||
@@ -119,6 +154,7 @@ fun Slider(
|
||||
steppedOffsetXs = List(steps + 2) { index -> index * pOffsetX }
|
||||
}
|
||||
|
||||
/** Get the stepped offset X. */
|
||||
fun Float.withSteps() =
|
||||
if (steps > 0)
|
||||
steppedOffsetXs.minByOrNull { abs(it - this) } ?: this
|
||||
@@ -131,11 +167,13 @@ fun Slider(
|
||||
val animatedOffsetX by animateFloatAsState(offsetX)
|
||||
val adoptedOffsetX = if (tapped && !dragging) animatedOffsetX else offsetX
|
||||
|
||||
/** Update the value of slider. */
|
||||
fun updateValue(offsetX: Float) {
|
||||
val newValue = (offsetX / maxOffsetX) * (max - min) + min
|
||||
onValueChange(newValue)
|
||||
}
|
||||
|
||||
/** Build the track of slider. */
|
||||
@Composable
|
||||
fun Track(content: @Composable () -> Unit) {
|
||||
val cornerSize = (style.trackShape as? CornerBasedShape)?.topStart?.toPx(Size.Zero, LocalDensity.current) ?: 0f
|
||||
@@ -156,6 +194,7 @@ fun Slider(
|
||||
}
|
||||
}
|
||||
|
||||
/** Build the step of slider. */
|
||||
@Composable
|
||||
fun Step() {
|
||||
if (steps > 0) Row(
|
||||
@@ -172,6 +211,7 @@ fun Slider(
|
||||
}
|
||||
}
|
||||
|
||||
/** Build the thumb of slider. */
|
||||
@Composable
|
||||
fun Thumb() {
|
||||
Box(
|
||||
@@ -231,7 +271,10 @@ fun Slider(
|
||||
}
|
||||
}
|
||||
|
||||
object Slider {
|
||||
/**
|
||||
* Defaults of slider.
|
||||
*/
|
||||
object SliderDefaults {
|
||||
val colors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
|
@@ -40,18 +40,33 @@ import com.highcapable.betterandroid.compose.extension.ui.ComponentPadding
|
||||
import com.highcapable.flexiui.LocalColors
|
||||
import com.highcapable.flexiui.LocalSizes
|
||||
|
||||
/**
|
||||
* Colors defines for surface.
|
||||
* @param contentColor the content color, usually for the text color.
|
||||
* @param backgroundColor the background color.
|
||||
*/
|
||||
@Immutable
|
||||
data class SurfaceColors(
|
||||
val contentColor: Color,
|
||||
val backgroundColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI surface.
|
||||
*
|
||||
* A surface have a background color and default padding.
|
||||
* @param modifier the [Modifier] to be applied to this surface.
|
||||
* @param initializer the [Modifier] initializer, earlies than [modifier].
|
||||
* @param colors the colors of surface, default is [SurfaceDefaults.colors].
|
||||
* @param padding the padding of surface, default is [SurfaceDefaults.padding].
|
||||
* @param content the content of the [Surface].
|
||||
*/
|
||||
@Composable
|
||||
fun Surface(
|
||||
modifier: Modifier = Modifier,
|
||||
initializer: @Composable Modifier.() -> Modifier = { Modifier },
|
||||
colors: SurfaceColors = Surface.colors,
|
||||
padding: ComponentPadding = Surface.padding,
|
||||
colors: SurfaceColors = SurfaceDefaults.colors,
|
||||
padding: ComponentPadding = SurfaceDefaults.padding,
|
||||
content: @Composable BoxScope.() -> Unit
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
@@ -81,7 +96,10 @@ private fun Modifier.surface(
|
||||
.padding(padding)
|
||||
}
|
||||
|
||||
object Surface {
|
||||
/**
|
||||
* Defaults of surface.
|
||||
*/
|
||||
object SurfaceDefaults {
|
||||
val colors: SurfaceColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
|
@@ -67,6 +67,12 @@ import com.highcapable.flexiui.LocalShapes
|
||||
import com.highcapable.flexiui.LocalSizes
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* Colors defines for switch.
|
||||
* @param thumbColor the color of thumb.
|
||||
* @param trackInactive the color of track when switch is inactive.
|
||||
* @param trackActive the color of track when switch is active.
|
||||
*/
|
||||
@Immutable
|
||||
data class SwitchColors(
|
||||
val thumbColor: Color,
|
||||
@@ -74,6 +80,20 @@ data class SwitchColors(
|
||||
val trackActive: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for switch.
|
||||
* @param padding the padding between thumb and track.
|
||||
* @param contentSpacing the spacing between content and track.
|
||||
* @param thumbRadius the radius of thumb.
|
||||
* @param thumbGain the gain of thumb when switch is hovered or dragging.
|
||||
* @param thumbShadowSize the shadow size of thumb.
|
||||
* @param thumbShape the shape of thumb.
|
||||
* @param trackShape the shape of track.
|
||||
* @param thumbBorder the border of thumb.
|
||||
* @param trackBorder the border of track.
|
||||
* @param trackWidth the width of track.
|
||||
* @param trackHeight the height of track.
|
||||
*/
|
||||
@Immutable
|
||||
data class SwitchStyle(
|
||||
val padding: ComponentPadding,
|
||||
@@ -89,13 +109,24 @@ data class SwitchStyle(
|
||||
val trackHeight: Dp
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI switch.
|
||||
* @param checked the checked state of switch.
|
||||
* @param onCheckedChange the callback when switch checked state changed.
|
||||
* @param modifier the [Modifier] to be applied to this switch.
|
||||
* @param colors the colors of switch, default is [SwitchDefaults.colors].
|
||||
* @param style the style of switch, default is [SwitchDefaults.style].
|
||||
* @param enabled the enabled state of switch, default is true.
|
||||
* @param interactionSource the interaction source of switch.
|
||||
* @param content the content of the [RowScope] to be applied to the [Switch], should typically be [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun Switch(
|
||||
checked: Boolean,
|
||||
onCheckedChange: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: SwitchColors = Switch.colors,
|
||||
style: SwitchStyle = Switch.style,
|
||||
colors: SwitchColors = SwitchDefaults.colors,
|
||||
style: SwitchStyle = SwitchDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable (RowScope.() -> Unit)? = null
|
||||
@@ -112,6 +143,8 @@ fun Switch(
|
||||
val animatedOffsetX by animateFloatAsState(offsetX)
|
||||
val animatedScale by animateFloatAsState(if (hovered || dragging) style.thumbGain else 1f)
|
||||
var trackColor by remember { mutableStateOf(colors.trackInactive) }
|
||||
|
||||
/** Update the track color of switch. */
|
||||
fun updateTrackColor() {
|
||||
val fraction = (offsetX / maxOffsetX).coerceIn(0f, 1f)
|
||||
trackColor = lerp(colors.trackInactive, colors.trackActive, fraction)
|
||||
@@ -120,6 +153,7 @@ fun Switch(
|
||||
val animatedTrackColor by animateColorAsState(trackColor)
|
||||
val efficientDragging = dragging && distance > 5
|
||||
|
||||
/** Build the track of switch. */
|
||||
@Composable
|
||||
fun Track(content: @Composable RowScope.() -> Unit) {
|
||||
Row(
|
||||
@@ -140,6 +174,7 @@ fun Switch(
|
||||
)
|
||||
}
|
||||
|
||||
/** Build the thumb of switch. */
|
||||
@Composable
|
||||
fun Thumb() {
|
||||
Box(
|
||||
@@ -193,7 +228,10 @@ fun Switch(
|
||||
}
|
||||
}
|
||||
|
||||
object Switch {
|
||||
/**
|
||||
* Defaults of switch.
|
||||
*/
|
||||
object SwitchDefaults {
|
||||
val colors: SwitchColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
|
@@ -80,6 +80,12 @@ import com.highcapable.flexiui.interaction.rippleClickable
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Colors defines for tab.
|
||||
* @param indicatorColor the indicator color.
|
||||
* @param selectedContentColor the selected content color.
|
||||
* @param unselectedContentColor the unselected content color.
|
||||
*/
|
||||
@Immutable
|
||||
data class TabColors(
|
||||
val indicatorColor: Color,
|
||||
@@ -87,6 +93,14 @@ data class TabColors(
|
||||
val unselectedContentColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for tab.
|
||||
* @param contentPadding the content padding.
|
||||
* @param contentShape the content shape.
|
||||
* @param indicatorWidth the indicator width.
|
||||
* @param indicatorHeight the indicator height.
|
||||
* @param indicatorShape the indicator shape.
|
||||
*/
|
||||
@Immutable
|
||||
data class TabStyle(
|
||||
val contentPadding: ComponentPadding,
|
||||
@@ -96,12 +110,23 @@ data class TabStyle(
|
||||
val indicatorShape: Shape
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI fixed tabs.
|
||||
* @see ScrollableTabRow
|
||||
* @see Tab
|
||||
* @param selectedTabIndex the selected tab index.
|
||||
* @param modifier the [Modifier] to be applied to tabs.
|
||||
* @param colors the colors of tabs, default is [TabDefaults.colors].
|
||||
* @param style the style of tabs, default is [TabDefaults.style].
|
||||
* @param indicator the indicator of the [TabRow], see [TabRowScope.TabIndicator].
|
||||
* @param tabs the tabs of the [TabRow], should typically be [Tab].
|
||||
*/
|
||||
@Composable
|
||||
fun TabRow(
|
||||
selectedTabIndex: Int = 0,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: TabColors = Tab.colors,
|
||||
style: TabStyle = Tab.style,
|
||||
colors: TabColors = TabDefaults.colors,
|
||||
style: TabStyle = TabDefaults.style,
|
||||
indicator: @Composable TabRowScope.() -> Unit = { TabIndicator(modifier = Modifier.tabIndicatorOffset()) },
|
||||
tabs: @Composable () -> Unit
|
||||
) {
|
||||
@@ -136,12 +161,24 @@ fun TabRow(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI scrollable tabs.
|
||||
* @see TabRow
|
||||
* @see Tab
|
||||
* @param selectedTabIndex the selected tab index.
|
||||
* @param modifier the [Modifier] to be applied to tabs.
|
||||
* @param colors the colors of tabs, default is [TabDefaults.colors].
|
||||
* @param style the style of tabs, default is [TabDefaults.style].
|
||||
* @param scrollState the scroll state of tabs.
|
||||
* @param indicator the indicator of the [ScrollableTabRow], see [TabRowScope.TabIndicator].
|
||||
* @param tabs the tabs of the [ScrollableTabRow], should typically be [Tab].
|
||||
*/
|
||||
@Composable
|
||||
fun ScrollableTabRow(
|
||||
selectedTabIndex: Int = 0,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: TabColors = Tab.colors,
|
||||
style: TabStyle = Tab.style,
|
||||
colors: TabColors = TabDefaults.colors,
|
||||
style: TabStyle = TabDefaults.style,
|
||||
scrollState: ScrollState = rememberScrollState(),
|
||||
indicator: @Composable TabRowScope.() -> Unit = { TabIndicator(modifier = Modifier.tabIndicatorOffset()) },
|
||||
tabs: @Composable () -> Unit
|
||||
@@ -190,6 +227,21 @@ fun ScrollableTabRow(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI tab.
|
||||
* @see TabRow
|
||||
* @see ScrollableTabRow
|
||||
* @param selected whether this tab is selected.
|
||||
* @param onClick the callback when this tab is clicked.
|
||||
* @param modifier the [Modifier] to be applied to this tab.
|
||||
* @param selectedContentColor the selected content color.
|
||||
* @param unselectedContentColor the unselected content color.
|
||||
* @param contentPadding the content padding.
|
||||
* @param contentShape the content shape.
|
||||
* @param enabled whether this tab is enabled.
|
||||
* @param interactionSource the interaction source.
|
||||
* @param content the content of the [Tab], should typically be [Icon] or [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun Tab(
|
||||
selected: Boolean,
|
||||
@@ -204,11 +256,11 @@ fun Tab(
|
||||
content: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
val currentSelectedContentColor = selectedContentColor.orNull()
|
||||
?: LocalTabSelectedContentColor.current.orNull() ?: Tab.colors.selectedContentColor
|
||||
?: LocalTabSelectedContentColor.current.orNull() ?: TabDefaults.colors.selectedContentColor
|
||||
val currentUnselectedContentColor = unselectedContentColor.orNull()
|
||||
?: LocalTabUnselectedContentColor.current.orNull() ?: Tab.colors.unselectedContentColor
|
||||
val currentContentPadding = contentPadding ?: LocalTabContentPadding.current ?: Tab.style.contentPadding
|
||||
val currentContentShape = contentShape ?: LocalTabContentShape.current ?: Tab.style.contentShape
|
||||
?: LocalTabUnselectedContentColor.current.orNull() ?: TabDefaults.colors.unselectedContentColor
|
||||
val currentContentPadding = contentPadding ?: LocalTabContentPadding.current ?: TabDefaults.style.contentPadding
|
||||
val currentContentShape = contentShape ?: LocalTabContentShape.current ?: TabDefaults.style.contentShape
|
||||
val contentColor by animateColorAsState(if (selected) currentSelectedContentColor else currentUnselectedContentColor)
|
||||
val contentIconStyle = LocalIconStyle.current.copy(tint = contentColor)
|
||||
val contentTextStyle = LocalTextStyle.current.copy(color = contentColor)
|
||||
@@ -257,17 +309,41 @@ private fun rememberScrollableTabData(scrollState: ScrollState): ScrollableTabDa
|
||||
return remember(scrollState, coroutineScope) { ScrollableTabData(scrollState, coroutineScope) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the position of a tab.
|
||||
* @param left the left position.
|
||||
* @param width the indicator width.
|
||||
* @param tabWidth the tab width.
|
||||
*/
|
||||
@Immutable
|
||||
data class TabPosition(val left: Dp, val width: Dp, val tabWidth: Dp) {
|
||||
|
||||
/**
|
||||
* Calculates the right of the tab.
|
||||
* @return [Dp]
|
||||
*/
|
||||
val right get() = left + width
|
||||
|
||||
/**
|
||||
* Calculates the center of the tab.
|
||||
* @param currentWidth the current indicator width.
|
||||
*/
|
||||
fun calculateCenter(currentWidth: Dp) = left + width / 2 - currentWidth / 2
|
||||
}
|
||||
|
||||
/**
|
||||
* A scope for tab.
|
||||
*/
|
||||
@Stable
|
||||
interface TabRowScope {
|
||||
|
||||
/**
|
||||
* Tab indicator.
|
||||
* @param modifier the [Modifier] to be applied to this tab indicator.
|
||||
* @param color the color of this tab indicator.
|
||||
* @param height the height of this tab indicator.
|
||||
* @param shape the shape of this tab indicator.
|
||||
*/
|
||||
@Composable
|
||||
fun TabIndicator(
|
||||
modifier: Modifier = Modifier,
|
||||
@@ -278,6 +354,11 @@ interface TabRowScope {
|
||||
Box(modifier.height(height).background(color, shape))
|
||||
}
|
||||
|
||||
/**
|
||||
* [Modifier] that offsets the tab indicator.
|
||||
* @param currentTabPosition the current tab position.
|
||||
* @param indicatorWidth the indicator width.
|
||||
*/
|
||||
fun Modifier.tabIndicatorOffset(
|
||||
currentTabPosition: TabPosition = impl.tabPositions[impl.selectedTabIndex],
|
||||
indicatorWidth: Dp = impl.style.indicatorWidth
|
||||
@@ -303,6 +384,12 @@ interface TabRowScope {
|
||||
.width(animatedWidh)
|
||||
}
|
||||
|
||||
/**
|
||||
* [Modifier] that offsets the pager tab indicator.
|
||||
* @param pagerState the pager state.
|
||||
* @param tabPositions the tab positions.
|
||||
* @param indicatorWidth the indicator width.
|
||||
*/
|
||||
fun Modifier.pagerTabIndicatorOffset(
|
||||
pagerState: PagerState,
|
||||
tabPositions: List<TabPosition> = impl.tabPositions,
|
||||
@@ -415,7 +502,10 @@ private class ScrollableTabData(private val scrollState: ScrollState, private va
|
||||
@Stable
|
||||
private enum class TabSlots { Tabs, TabsAverage, Indicator }
|
||||
|
||||
object Tab {
|
||||
/**
|
||||
* Defaults of tab.
|
||||
*/
|
||||
object TabDefaults {
|
||||
val colors: TabColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
|
@@ -26,6 +26,7 @@ package com.highcapable.flexiui.component
|
||||
import androidx.compose.foundation.text.BasicText
|
||||
import androidx.compose.foundation.text.InlineTextContent
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -38,12 +39,26 @@ import com.highcapable.betterandroid.compose.extension.ui.orNull
|
||||
import com.highcapable.flexiui.DefaultTypography
|
||||
import com.highcapable.flexiui.LocalColors
|
||||
|
||||
/**
|
||||
* Flexi UI basic text.
|
||||
* @see BasicText
|
||||
* @param text the text to be displayed.
|
||||
* @param modifier the [Modifier] to be applied to this text.
|
||||
* @param color the color of the text.
|
||||
* @param style the style of the text.
|
||||
* @param singleLine whether the text should be displayed on a single line, default is false.
|
||||
* @param maxLines the maximum number of lines to display, when [singleLine] is false default is [Int.MAX_VALUE].
|
||||
* @param minLines the minimum number of lines to display, default is 1.
|
||||
* @param overflow the overflow strategy for displaying the text, default is [TextOverflow.Ellipsis].
|
||||
* @param softWrap whether the text should break at soft line breaks.
|
||||
* @param onTextLayout the callback to be invoked when the text layout is ready.
|
||||
*/
|
||||
@Composable
|
||||
fun Text(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
color: Color = Color.Unspecified,
|
||||
style: TextStyle = Text.style,
|
||||
style: TextStyle? = null,
|
||||
singleLine: Boolean = false,
|
||||
maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
|
||||
minLines: Int = 1,
|
||||
@@ -65,12 +80,27 @@ fun Text(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI basic text.
|
||||
* @see BasicText
|
||||
* @param text the text to be displayed.
|
||||
* @param modifier the [Modifier] to be applied to this text.
|
||||
* @param color the color of the text.
|
||||
* @param style the style of the text.
|
||||
* @param singleLine whether the text should be displayed on a single line, default is false.
|
||||
* @param maxLines the maximum number of lines to display, when [singleLine] is false default is [Int.MAX_VALUE].
|
||||
* @param minLines the minimum number of lines to display, default is 1.
|
||||
* @param overflow the overflow strategy for displaying the text, default is [TextOverflow.Ellipsis].
|
||||
* @param softWrap whether the text should break at soft line breaks.
|
||||
* @param inlineContent map of tags to [InlineTextContent]s that can be used to add composable content to the text.
|
||||
* @param onTextLayout the callback to be invoked when the text layout is ready.
|
||||
*/
|
||||
@Composable
|
||||
fun Text(
|
||||
text: AnnotatedString,
|
||||
modifier: Modifier = Modifier,
|
||||
color: Color = Color.Unspecified,
|
||||
style: TextStyle = Text.style,
|
||||
style: TextStyle? = null,
|
||||
singleLine: Boolean = false,
|
||||
maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
|
||||
minLines: Int = 1,
|
||||
@@ -79,11 +109,12 @@ fun Text(
|
||||
inlineContent: Map<String, InlineTextContent> = mapOf(),
|
||||
onTextLayout: (TextLayoutResult) -> Unit = {}
|
||||
) {
|
||||
val currentColor = color.orNull() ?: style.color.orNull() ?: Text.color
|
||||
val currentStyle = style ?: LocalTextStyle.current
|
||||
val currentColor = color.orNull() ?: currentStyle.color.orNull() ?: defaultTextColor()
|
||||
BasicText(
|
||||
text = text,
|
||||
modifier = modifier,
|
||||
style = style.copy(color = currentColor),
|
||||
style = currentStyle.copy(color = currentColor),
|
||||
onTextLayout = onTextLayout,
|
||||
overflow = overflow,
|
||||
softWrap = softWrap,
|
||||
@@ -93,21 +124,28 @@ fun Text(
|
||||
)
|
||||
}
|
||||
|
||||
object Text {
|
||||
val color: Color
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = defaultTextColor()
|
||||
val style: TextStyle
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = LocalTextStyle.current
|
||||
/**
|
||||
* CompositionLocal containing the preferred [TextStyle]
|
||||
* that will be used by text by default.
|
||||
*/
|
||||
val LocalTextStyle = compositionLocalOf { DefaultTextStyle }
|
||||
|
||||
/**
|
||||
* This function is used to set the current value of [LocalTextStyle], merging the given style
|
||||
* with the current style values for any missing attributes. Any [Text] components included in
|
||||
* this component's [content] will be styled with this style unless styled explicitly.
|
||||
* @see LocalTextStyle
|
||||
* @param value the merged text style to set.
|
||||
* @param content the composable content.
|
||||
*/
|
||||
@Composable
|
||||
fun ProvideTextStyle(value: TextStyle, content: @Composable () -> Unit) {
|
||||
val mergedStyle = LocalTextStyle.current.merge(value)
|
||||
CompositionLocalProvider(LocalTextStyle provides mergedStyle, content = content)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
internal fun defaultTextColor() = LocalColors.current.textPrimary
|
||||
|
||||
internal val LocalTextStyle = compositionLocalOf { DefaultTextStyle }
|
||||
|
||||
private val DefaultTextStyle = DefaultTypography.primary
|
@@ -97,6 +97,19 @@ import com.highcapable.flexiui.resources.icon.Backspace
|
||||
import com.highcapable.flexiui.resources.icon.ViewerClose
|
||||
import com.highcapable.flexiui.resources.icon.ViewerOpen
|
||||
|
||||
/**
|
||||
* Colors defines for text field.
|
||||
* @param textColor the text color.
|
||||
* @param cursorColor the cursor color.
|
||||
* @param selectionColors the selection colors.
|
||||
* @param completionColors the completion colors.
|
||||
* @param placeholderContentColor the placeholder content color, usually for text color.
|
||||
* @param decorInactiveTint the decoration inactive tint.
|
||||
* @param decorActiveTint the decoration active tint.
|
||||
* @param borderInactiveColor the border inactive color.
|
||||
* @param borderActiveColor the border active color.
|
||||
* @param backgroundColor the background color.
|
||||
*/
|
||||
@Immutable
|
||||
data class TextFieldColors(
|
||||
val textColor: Color,
|
||||
@@ -111,12 +124,26 @@ data class TextFieldColors(
|
||||
val backgroundColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Colors defines for auto complete box.
|
||||
* @param highlightContentColor the highlight content color, usually for text color.
|
||||
* @param menuColors the dropdown menu colors.
|
||||
*/
|
||||
@Immutable
|
||||
data class AutoCompleteBoxColors(
|
||||
val highlightContentColor: Color,
|
||||
val menuColors: DropdownMenuColors
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for text field.
|
||||
* @param textStyle the text style.
|
||||
* @param padding the padding of content.
|
||||
* @param shape the shape.
|
||||
* @param borderInactive the inactive border stroke.
|
||||
* @param borderActive the active border stroke.
|
||||
* @param completionStyle the completion dropdown menu style.
|
||||
*/
|
||||
@Immutable
|
||||
data class TextFieldStyle(
|
||||
val textStyle: TextStyle,
|
||||
@@ -127,6 +154,13 @@ data class TextFieldStyle(
|
||||
val completionStyle: DropdownMenuStyle
|
||||
)
|
||||
|
||||
/**
|
||||
* Options defines for auto complete.
|
||||
* @param checkCase whether to check case, default is true.
|
||||
* @param checkStartSpace whether to check start space, default is true.
|
||||
* @param checkEndSpace whether to check end space, default is true.
|
||||
* @param threshold the threshold, default is 2.
|
||||
*/
|
||||
@Immutable
|
||||
data class AutoCompleteOptions(
|
||||
val checkCase: Boolean = true,
|
||||
@@ -135,14 +169,41 @@ data class AutoCompleteOptions(
|
||||
val threshold: Int = 2
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI text field.
|
||||
* @see TextField
|
||||
* @see PasswordTextField
|
||||
* @see BackspaceTextField
|
||||
* @param value the text field value.
|
||||
* @param onValueChange the text field value change callback.
|
||||
* @param completionValues the auto complete values, when you want to use auto complete.
|
||||
* @param modifier the [Modifier] to be applied to this text field.
|
||||
* @param colors the colors of this text field, default is [TextFieldDefaults.colors].
|
||||
* @param style the style of this text field, default is [TextFieldDefaults.style].
|
||||
* @param enabled whether this text field is enabled, default is true.
|
||||
* @param readOnly whether this text field is read only, default is false.
|
||||
* @param completionOptions the auto complete options.
|
||||
* @param keyboardOptions the keyboard options, default is [KeyboardOptions.Default].
|
||||
* @param keyboardActions the keyboard actions, default is [KeyboardActions.Default].
|
||||
* @param singleLine whether this text field is single line, default is false.
|
||||
* @param maxLines the max lines of this text field, when [singleLine] is false default is [Int.MAX_VALUE].
|
||||
* @param minLines the min lines of this text field, default is 1.
|
||||
* @param visualTransformation the visual transformation, default is [VisualTransformation.None].
|
||||
* @param onTextLayout the callback to be invoked when the text layout is ready.
|
||||
* @param focusRequester the focus requester of this text field.
|
||||
* @param interactionSource the interaction source of this text field.
|
||||
* @param header the header of the [TextField], should typically be [Icon] or [Text].
|
||||
* @param placeholder the placeholder of the [TextField], should typically be [Icon] or [Text].
|
||||
* @param footer the footer of the [TextField], should typically be [Icon] or [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun TextField(
|
||||
value: TextFieldValue,
|
||||
onValueChange: (TextFieldValue) -> Unit,
|
||||
completionValues: List<String> = emptyList(),
|
||||
modifier: Modifier = Modifier,
|
||||
colors: TextFieldColors = TextField.colors,
|
||||
style: TextFieldStyle = TextField.style,
|
||||
colors: TextFieldColors = TextFieldDefaults.colors,
|
||||
style: TextFieldStyle = TextFieldDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
readOnly: Boolean = false,
|
||||
completionOptions: AutoCompleteOptions = AutoCompleteOptions(),
|
||||
@@ -257,14 +318,41 @@ fun TextField(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI text field.
|
||||
* @see TextField
|
||||
* @see PasswordTextField
|
||||
* @see BackspaceTextField
|
||||
* @param value the value of text.
|
||||
* @param onValueChange the text field value change callback.
|
||||
* @param completionValues the auto complete values, when you want to use auto complete.
|
||||
* @param modifier the [Modifier] to be applied to this text field.
|
||||
* @param colors the colors of this text field, default is [TextFieldDefaults.colors].
|
||||
* @param style the style of this text field, default is [TextFieldDefaults.style].
|
||||
* @param enabled whether this text field is enabled, default is true.
|
||||
* @param readOnly whether this text field is read only, default is false.
|
||||
* @param completionOptions the auto complete options.
|
||||
* @param keyboardOptions the keyboard options, default is [KeyboardOptions.Default].
|
||||
* @param keyboardActions the keyboard actions, default is [KeyboardActions.Default].
|
||||
* @param singleLine whether this text field is single line, default is false.
|
||||
* @param maxLines the max lines of this text field, when [singleLine] is false default is [Int.MAX_VALUE].
|
||||
* @param minLines the min lines of this text field, default is 1.
|
||||
* @param visualTransformation the visual transformation, default is [VisualTransformation.None].
|
||||
* @param onTextLayout the callback to be invoked when the text layout is ready.
|
||||
* @param focusRequester the focus requester of this text field.
|
||||
* @param interactionSource the interaction source of this text field.
|
||||
* @param header the header of the [TextField], should typically be [Icon] or [Text].
|
||||
* @param placeholder the placeholder of the [TextField], should typically be [Icon] or [Text].
|
||||
* @param footer the footer of the [TextField], should typically be [Icon] or [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun TextField(
|
||||
value: String,
|
||||
onValueChange: (String) -> Unit,
|
||||
completionValues: List<String> = emptyList(),
|
||||
modifier: Modifier = Modifier,
|
||||
colors: TextFieldColors = TextField.colors,
|
||||
style: TextFieldStyle = TextField.style,
|
||||
colors: TextFieldColors = TextFieldDefaults.colors,
|
||||
style: TextFieldStyle = TextFieldDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
readOnly: Boolean = false,
|
||||
completionOptions: AutoCompleteOptions = AutoCompleteOptions(),
|
||||
@@ -310,14 +398,37 @@ fun TextField(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI password text field.
|
||||
* @see TextField
|
||||
* @see PasswordTextField
|
||||
* @see BackspaceTextField
|
||||
* @param value the text field value.
|
||||
* @param onValueChange the text field value change callback.
|
||||
* @param defaultPasswordVisible the default password visible, default is false.
|
||||
* @param modifier the [Modifier] to be applied to this text field.
|
||||
* @param colors the colors of this text field, default is [TextFieldDefaults.colors].
|
||||
* @param style the style of this text field, default is [TextFieldDefaults.style].
|
||||
* @param enabled whether this text field is enabled, default is true.
|
||||
* @param readOnly whether this text field is read only, default is false.
|
||||
* @param keyboardOptions the keyboard options, default is [KeyboardOptions.Default].
|
||||
* @param keyboardActions the keyboard actions, default is [KeyboardActions.Default].
|
||||
* @param normalVisualTransformation the normal visual transformation, default is [VisualTransformation.None].
|
||||
* @param secretVisualTransformation the secret visual transformation, default is [PasswordVisualTransformation].
|
||||
* @param onTextLayout the callback to be invoked when the text layout is ready.
|
||||
* @param focusRequester the focus requester of this text field.
|
||||
* @param interactionSource the interaction source of this text field.
|
||||
* @param header the header of the [TextField], should typically be [Icon] or [Text].
|
||||
* @param placeholder the placeholder of the [TextField], should typically be [Icon] or [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun PasswordTextField(
|
||||
value: TextFieldValue,
|
||||
onValueChange: (TextFieldValue) -> Unit,
|
||||
defaultPasswordVisible: Boolean = false,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: TextFieldColors = TextField.colors,
|
||||
style: TextFieldStyle = TextField.style,
|
||||
colors: TextFieldColors = TextFieldDefaults.colors,
|
||||
style: TextFieldStyle = TextFieldDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
readOnly: Boolean = false,
|
||||
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
|
||||
@@ -364,7 +475,7 @@ fun PasswordTextField(
|
||||
if (value.text.isEmpty() && animatedSize == 0.dp) passwordVisible = defaultPasswordVisible
|
||||
IconToggleButton(
|
||||
modifier = Modifier.size(animatedSize).pointerHoverState(TextFieldPointerState.Common),
|
||||
style = IconButton.style.copy(padding = TextDecorIconPadding),
|
||||
style = IconButtonDefaults.style.copy(padding = TextDecorIconPadding),
|
||||
checked = passwordVisible,
|
||||
onCheckedChange = {
|
||||
passwordVisible = it
|
||||
@@ -378,14 +489,37 @@ fun PasswordTextField(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI password text field.
|
||||
* @see TextField
|
||||
* @see PasswordTextField
|
||||
* @see BackspaceTextField
|
||||
* @param value the value of text.
|
||||
* @param onValueChange the text field value change callback.
|
||||
* @param defaultPasswordVisible the default password visible, default is false.
|
||||
* @param modifier the [Modifier] to be applied to this text field.
|
||||
* @param colors the colors of this text field, default is [TextFieldDefaults.colors].
|
||||
* @param style the style of this text field, default is [TextFieldDefaults.style].
|
||||
* @param enabled whether this text field is enabled, default is true.
|
||||
* @param readOnly whether this text field is read only, default is false.
|
||||
* @param keyboardOptions the keyboard options, default is [KeyboardOptions.Default].
|
||||
* @param keyboardActions the keyboard actions, default is [KeyboardActions.Default].
|
||||
* @param normalVisualTransformation the normal visual transformation, default is [VisualTransformation.None].
|
||||
* @param secretVisualTransformation the secret visual transformation, default is [PasswordVisualTransformation].
|
||||
* @param onTextLayout the callback to be invoked when the text layout is ready.
|
||||
* @param focusRequester the focus requester of this text field.
|
||||
* @param interactionSource the interaction source of this text field.
|
||||
* @param header the header of the [TextField], should typically be [Icon] or [Text].
|
||||
* @param placeholder the placeholder of the [TextField], should typically be [Icon] or [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun PasswordTextField(
|
||||
value: String,
|
||||
onValueChange: (String) -> Unit,
|
||||
defaultPasswordVisible: Boolean = false,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: TextFieldColors = TextField.colors,
|
||||
style: TextFieldStyle = TextField.style,
|
||||
colors: TextFieldColors = TextFieldDefaults.colors,
|
||||
style: TextFieldStyle = TextFieldDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
readOnly: Boolean = false,
|
||||
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
|
||||
@@ -423,14 +557,40 @@ fun PasswordTextField(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI text field with backspace icon.
|
||||
* @see TextField
|
||||
* @see PasswordTextField
|
||||
* @see BackspaceTextField
|
||||
* @param value the text field value.
|
||||
* @param onValueChange the text field value change callback.
|
||||
* @param completionValues the auto complete values, when you want to use auto complete.
|
||||
* @param modifier the [Modifier] to be applied to this text field.
|
||||
* @param colors the colors of this text field, default is [TextFieldDefaults.colors].
|
||||
* @param style the style of this text field, default is [TextFieldDefaults.style].
|
||||
* @param enabled whether this text field is enabled, default is true.
|
||||
* @param readOnly whether this text field is read only, default is false.
|
||||
* @param completionOptions the auto complete options.
|
||||
* @param keyboardOptions the keyboard options, default is [KeyboardOptions.Default].
|
||||
* @param keyboardActions the keyboard actions, default is [KeyboardActions.Default].
|
||||
* @param singleLine whether this text field is single line, default is false.
|
||||
* @param maxLines the max lines of this text field, when [singleLine] is false default is [Int.MAX_VALUE].
|
||||
* @param minLines the min lines of this text field, default is 1.
|
||||
* @param visualTransformation the visual transformation, default is [VisualTransformation.None].
|
||||
* @param onTextLayout the callback to be invoked when the text layout is ready.
|
||||
* @param focusRequester the focus requester of this text field.
|
||||
* @param interactionSource the interaction source of this text field.
|
||||
* @param header the header of the [TextField], should typically be [Icon] or [Text].
|
||||
* @param placeholder the placeholder of the [TextField], should typically be [Icon] or [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun BackspaceTextField(
|
||||
value: TextFieldValue,
|
||||
onValueChange: (TextFieldValue) -> Unit,
|
||||
completionValues: List<String> = emptyList(),
|
||||
modifier: Modifier = Modifier,
|
||||
colors: TextFieldColors = TextField.colors,
|
||||
style: TextFieldStyle = TextField.style,
|
||||
colors: TextFieldColors = TextFieldDefaults.colors,
|
||||
style: TextFieldStyle = TextFieldDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
readOnly: Boolean = false,
|
||||
completionOptions: AutoCompleteOptions = AutoCompleteOptions(),
|
||||
@@ -487,7 +647,7 @@ fun BackspaceTextField(
|
||||
focusRequester.requestFocus()
|
||||
},
|
||||
modifier = Modifier.width(animatedSize).pointerHoverState(TextFieldPointerState.Common),
|
||||
style = IconButton.style.copy(padding = TextDecorIconPadding),
|
||||
style = IconButtonDefaults.style.copy(padding = TextDecorIconPadding),
|
||||
enabled = enabled,
|
||||
interactionSource = cInteractionSource
|
||||
) { Icon(imageVector = Icons.Backspace) }
|
||||
@@ -496,14 +656,40 @@ fun BackspaceTextField(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Flexi UI text field with backspace icon.
|
||||
* @see TextField
|
||||
* @see PasswordTextField
|
||||
* @see BackspaceTextField
|
||||
* @param value the value of text.
|
||||
* @param onValueChange the text field value change callback.
|
||||
* @param completionValues the auto complete values, when you want to use auto complete.
|
||||
* @param modifier the [Modifier] to be applied to this text field.
|
||||
* @param colors the colors of this text field, default is [TextFieldDefaults.colors].
|
||||
* @param style the style of this text field, default is [TextFieldDefaults.style].
|
||||
* @param enabled whether this text field is enabled, default is true.
|
||||
* @param readOnly whether this text field is read only, default is false.
|
||||
* @param completionOptions the auto complete options.
|
||||
* @param keyboardOptions the keyboard options, default is [KeyboardOptions.Default].
|
||||
* @param keyboardActions the keyboard actions, default is [KeyboardActions.Default].
|
||||
* @param singleLine whether this text field is single line, default is false.
|
||||
* @param maxLines the max lines of this text field, when [singleLine] is false default is [Int.MAX_VALUE].
|
||||
* @param minLines the min lines of this text field, default is 1.
|
||||
* @param visualTransformation the visual transformation, default is [VisualTransformation.None].
|
||||
* @param onTextLayout the callback to be invoked when the text layout is ready.
|
||||
* @param focusRequester the focus requester of this text field.
|
||||
* @param interactionSource the interaction source of this text field.
|
||||
* @param header the header of the [TextField], should typically be [Icon] or [Text].
|
||||
* @param placeholder the placeholder of the [TextField], should typically be [Icon] or [Text].
|
||||
*/
|
||||
@Composable
|
||||
fun BackspaceTextField(
|
||||
value: String,
|
||||
onValueChange: (String) -> Unit,
|
||||
completionValues: List<String> = emptyList(),
|
||||
modifier: Modifier = Modifier,
|
||||
colors: TextFieldColors = TextField.colors,
|
||||
style: TextFieldStyle = TextField.style,
|
||||
colors: TextFieldColors = TextFieldDefaults.colors,
|
||||
style: TextFieldStyle = TextFieldDefaults.style,
|
||||
enabled: Boolean = true,
|
||||
readOnly: Boolean = false,
|
||||
completionOptions: AutoCompleteOptions = AutoCompleteOptions(),
|
||||
@@ -563,7 +749,7 @@ private fun AutoCompleteTextFieldBox(
|
||||
if (completionValues.isEmpty()) return
|
||||
// We need to use some "last" to remember the last using data,
|
||||
// because we need to mantain the animation state of the dropdown menu.
|
||||
// This allows the animation to finish playing due to the next composable event.
|
||||
// This allows the animation to finish playing due to the next compostion.
|
||||
var lastHandingModified by remember { mutableStateOf(false) }
|
||||
var lastMatchedValue by remember { mutableStateOf("") }
|
||||
var lastInputLength by remember { mutableStateOf(0) }
|
||||
@@ -597,9 +783,13 @@ private fun AutoCompleteTextFieldBox(
|
||||
lastHandingModified = false
|
||||
lastMatchedValue = ""
|
||||
} else selection = -1
|
||||
|
||||
/** Collapse the dropdown menu. */
|
||||
fun collapse() {
|
||||
lastMatchedValue = inputText
|
||||
}
|
||||
|
||||
/** Select and collapse the dropdown menu. */
|
||||
fun selectAndCollapse(position: Int) {
|
||||
if (position < 0) return
|
||||
val newValue = TextFieldValue(matchedValues[position], TextRange(matchedValues[position].length))
|
||||
@@ -746,7 +936,10 @@ private fun Modifier.textFieldPadding(
|
||||
}
|
||||
}
|
||||
|
||||
object TextField {
|
||||
/**
|
||||
* Defaults of text field.
|
||||
*/
|
||||
object TextFieldDefaults {
|
||||
val colors: TextFieldColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
@@ -768,7 +961,7 @@ private fun defaultTextFieldColors() = TextFieldColors(
|
||||
),
|
||||
completionColors = AutoCompleteBoxColors(
|
||||
highlightContentColor = LocalColors.current.themePrimary,
|
||||
menuColors = DropdownMenu.colors
|
||||
menuColors = DropdownMenuDefaults.colors
|
||||
),
|
||||
placeholderContentColor = LocalColors.current.textSecondary,
|
||||
decorInactiveTint = LocalColors.current.themeSecondary,
|
||||
@@ -786,7 +979,7 @@ private fun defaultTextFieldStyle() = TextFieldStyle(
|
||||
shape = withAreaBoxShape(),
|
||||
borderInactive = defaultTextFieldInactiveBorder(),
|
||||
borderActive = defaultTextFieldActiveBorder(),
|
||||
completionStyle = DropdownMenu.style
|
||||
completionStyle = DropdownMenuDefaults.style
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
package com.highcapable.flexiui.interaction
|
||||
|
||||
import androidx.compose.foundation.Indication
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
@@ -41,6 +42,12 @@ import com.highcapable.betterandroid.compose.extension.ui.toggleable
|
||||
import com.highcapable.flexiui.LocalColors
|
||||
import androidx.compose.material.ripple.rememberRipple as materialRememberRipple
|
||||
|
||||
/**
|
||||
* Style defines for ripple.
|
||||
* @param bounded whether the ripple is bounded.
|
||||
* @param radius the radius.
|
||||
* @param color the color.
|
||||
*/
|
||||
@Immutable
|
||||
data class RippleStyle(
|
||||
val bounded: Boolean,
|
||||
@@ -48,9 +55,26 @@ data class RippleStyle(
|
||||
val color: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Creates and remember a ripple effect [Indication] with the given [style].
|
||||
* @see materialRememberRipple
|
||||
* @param style the style, default is [InteractionDefaults.rippleStyle].
|
||||
* @return [Indication]
|
||||
*/
|
||||
@Composable
|
||||
fun rememberRipple(style: RippleStyle) = materialRememberRipple(style.bounded, style.radius, style.color)
|
||||
fun rememberRipple(style: RippleStyle = InteractionDefaults.rippleStyle) =
|
||||
materialRememberRipple(style.bounded, style.radius, style.color)
|
||||
|
||||
/**
|
||||
* The clickable modifier has a ripple effect.
|
||||
* @see Modifier.clickable
|
||||
* @param rippleStyle the ripple style, default is [InteractionDefaults.rippleStyle].
|
||||
* @param interactionSource the interaction source.
|
||||
* @param enabled whether to enable the event, default is true.
|
||||
* @param onClickLabel the click label.
|
||||
* @param role the role.
|
||||
* @param onClick the click event.
|
||||
*/
|
||||
fun Modifier.rippleClickable(
|
||||
rippleStyle: RippleStyle? = null,
|
||||
interactionSource: MutableInteractionSource? = null,
|
||||
@@ -69,7 +93,7 @@ fun Modifier.rippleClickable(
|
||||
properties["onClick"] = onClick
|
||||
}
|
||||
) {
|
||||
val currentRippleStyle = rippleStyle ?: Interaction.rippleStyle
|
||||
val currentRippleStyle = rippleStyle ?: InteractionDefaults.rippleStyle
|
||||
val currentIndication = rememberRipple(currentRippleStyle)
|
||||
clickable(
|
||||
onClick = onClick,
|
||||
@@ -81,6 +105,19 @@ fun Modifier.rippleClickable(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The combined clickable modifier has a ripple effect.
|
||||
* @see Modifier.combinedClickable
|
||||
* @param rippleStyle the ripple style, default is [InteractionDefaults.rippleStyle].
|
||||
* @param interactionSource the interaction source.
|
||||
* @param enabled whether to enable the event, default is true.
|
||||
* @param onClickLabel the click label.
|
||||
* @param role the role.
|
||||
* @param onLongClickLabel the long click label.
|
||||
* @param onLongClick the long click event.
|
||||
* @param onDoubleClick the double click event.
|
||||
* @param onClick the click event.
|
||||
*/
|
||||
fun Modifier.rippleCombinedClickable(
|
||||
rippleStyle: RippleStyle? = null,
|
||||
interactionSource: MutableInteractionSource? = null,
|
||||
@@ -105,7 +142,7 @@ fun Modifier.rippleCombinedClickable(
|
||||
properties["onClick"] = onClick
|
||||
}
|
||||
) {
|
||||
val currentRippleStyle = rippleStyle ?: Interaction.rippleStyle
|
||||
val currentRippleStyle = rippleStyle ?: InteractionDefaults.rippleStyle
|
||||
val currentIndication = rememberRipple(currentRippleStyle)
|
||||
combinedClickable(
|
||||
onClick = onClick,
|
||||
@@ -120,6 +157,15 @@ fun Modifier.rippleCombinedClickable(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The toggleable modifier has a ripple effect.
|
||||
* @see Modifier.toggleable
|
||||
* @param rippleStyle the ripple style, default is [InteractionDefaults.rippleStyle].
|
||||
* @param interactionSource the interaction source.
|
||||
* @param enabled whether to enable the event, default is true.
|
||||
* @param role the role.
|
||||
* @param onValueChange the value change event.
|
||||
*/
|
||||
fun Modifier.rippleToggleable(
|
||||
value: Boolean,
|
||||
rippleStyle: RippleStyle? = null,
|
||||
@@ -138,7 +184,7 @@ fun Modifier.rippleToggleable(
|
||||
properties["onValueChange"] = onValueChange
|
||||
}
|
||||
) {
|
||||
val currentRippleStyle = rippleStyle ?: Interaction.rippleStyle
|
||||
val currentRippleStyle = rippleStyle ?: InteractionDefaults.rippleStyle
|
||||
val currentIndication = rememberRipple(currentRippleStyle)
|
||||
toggleable(
|
||||
value = value,
|
||||
@@ -150,6 +196,15 @@ fun Modifier.rippleToggleable(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The selectable modifier has a ripple effect.
|
||||
* @see Modifier.selectable
|
||||
* @param rippleStyle the ripple style, default is [InteractionDefaults.rippleStyle].
|
||||
* @param interactionSource the interaction source.
|
||||
* @param enabled whether to enable the event, default is true.
|
||||
* @param role the role.
|
||||
* @param onClick the click event.
|
||||
*/
|
||||
fun Modifier.rippleSelectable(
|
||||
selected: Boolean,
|
||||
rippleStyle: RippleStyle? = null,
|
||||
@@ -168,7 +223,7 @@ fun Modifier.rippleSelectable(
|
||||
properties["onClick"] = onClick
|
||||
}
|
||||
) {
|
||||
val currentRippleStyle = rippleStyle ?: Interaction.rippleStyle
|
||||
val currentRippleStyle = rippleStyle ?: InteractionDefaults.rippleStyle
|
||||
val currentIndication = rememberRipple(currentRippleStyle)
|
||||
selectable(
|
||||
selected = selected,
|
||||
@@ -180,13 +235,20 @@ fun Modifier.rippleSelectable(
|
||||
)
|
||||
}
|
||||
|
||||
object Interaction {
|
||||
/**
|
||||
* Defaults of interaction.
|
||||
*/
|
||||
object InteractionDefaults {
|
||||
val rippleStyle: RippleStyle
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = LocalRippleStyle.current ?: defaultRippleStyle()
|
||||
}
|
||||
|
||||
/**
|
||||
* CompositionLocal containing the preferred [RippleStyle]
|
||||
* that will be used by interaction by default.
|
||||
*/
|
||||
val LocalRippleStyle = compositionLocalOf<RippleStyle?> { null }
|
||||
|
||||
@Composable
|
||||
|
@@ -31,6 +31,8 @@ import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
@@ -55,17 +57,40 @@ import com.highcapable.flexiui.LocalColors
|
||||
import com.highcapable.flexiui.LocalSizes
|
||||
import com.highcapable.flexiui.LocalTypography
|
||||
import com.highcapable.flexiui.component.AreaBox
|
||||
import com.highcapable.flexiui.component.AreaBoxDefaults
|
||||
import com.highcapable.flexiui.component.AreaBoxStyle
|
||||
import com.highcapable.flexiui.component.Button
|
||||
import com.highcapable.flexiui.component.Icon
|
||||
import com.highcapable.flexiui.component.LocalIconStyle
|
||||
import com.highcapable.flexiui.component.LocalPrimaryButton
|
||||
import com.highcapable.flexiui.component.LocalTextStyle
|
||||
import com.highcapable.flexiui.component.Text
|
||||
import com.highcapable.flexiui.utils.SubcomposeRow
|
||||
|
||||
/**
|
||||
* Colors defines for flexi dialog.
|
||||
* @param titleTextColor the title text color.
|
||||
* @param titleIconTint the title icon tint.
|
||||
* @param contentTextColor the content text color.
|
||||
*/
|
||||
@Immutable
|
||||
data class FlexiDialogColors(
|
||||
val titleTextColor: Color,
|
||||
val titleIconTint: Color,
|
||||
val contentTextColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for flexi dialog.
|
||||
* @param boxStyle the style of area box.
|
||||
* @param titleTextStyle the title text style.
|
||||
* @param contentTextStyle the content text style.
|
||||
* @param maxWidth the dialog's max width.
|
||||
* @param outPadding the dialog's out padding.
|
||||
* @param titlePadding the title padding.
|
||||
* @param contentPadding the content padding.
|
||||
* @param buttonsSpacing the spacing between buttons.
|
||||
*/
|
||||
@Immutable
|
||||
data class FlexiDialogStyle(
|
||||
val boxStyle: AreaBoxStyle,
|
||||
@@ -78,29 +103,50 @@ data class FlexiDialogStyle(
|
||||
val buttonsSpacing: Dp
|
||||
)
|
||||
|
||||
/**
|
||||
* Flexi UI dialog.
|
||||
* @param visible the visible state of dialog.
|
||||
* @param onDismissRequest the callback when dismiss dialog.
|
||||
* @param modifier the [Modifier] to be applied to this dialog.
|
||||
* @param animated whether to animate the dialog, default is true.
|
||||
* @param colors the colors of dialog, default is [FlexiDialogDefaults.colors].
|
||||
* @param style the style of dialog, default is [FlexiDialogDefaults.style].
|
||||
* @param contentAlignment the alignment of dialog content, default is [Alignment.TopStart].
|
||||
* @param properties the properties of dialog, default is [DefaultDialogProperties].
|
||||
* @param title the title of the [FlexiDialog], should typically be [Icon] or [Text].
|
||||
* @param content the content of the [FlexiDialog].
|
||||
* @param confirmButton the confirm button of the [FlexiDialog], should typically be [Button].
|
||||
* @param cancelButton the cancel button of the [FlexiDialog], should typically be [Button].
|
||||
* @param neutralButton the neutral button of the [FlexiDialog], should typically be [Button].
|
||||
*/
|
||||
@Composable
|
||||
fun FlexiDialog(
|
||||
visible: Boolean,
|
||||
onDismissRequest: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
animated: Boolean = true,
|
||||
colors: FlexiDialogColors = FlexiDialog.colors,
|
||||
style: FlexiDialogStyle = FlexiDialog.style,
|
||||
colors: FlexiDialogColors = FlexiDialogDefaults.colors,
|
||||
style: FlexiDialogStyle = FlexiDialogDefaults.style,
|
||||
contentAlignment: Alignment = Alignment.TopStart,
|
||||
properties: DialogPropertiesWrapper = DefaultDialogProperties,
|
||||
title: (@Composable () -> Unit)? = null,
|
||||
title: (@Composable RowScope.() -> Unit)? = null,
|
||||
content: @Composable () -> Unit,
|
||||
confirmButton: @Composable (() -> Unit)? = null,
|
||||
cancelButton: @Composable (() -> Unit)? = null,
|
||||
neutralButton: @Composable (() -> Unit)? = null
|
||||
) {
|
||||
/** Build the content of dialog. */
|
||||
@Composable
|
||||
fun Content() {
|
||||
title?.also { content ->
|
||||
Box(modifier = Modifier.padding(style.titlePadding)) {
|
||||
CompositionLocalProvider(
|
||||
LocalTextStyle provides style.titleTextStyle.copy(color = colors.titleTextColor),
|
||||
content = content
|
||||
title?.also { titleContent ->
|
||||
CompositionLocalProvider(
|
||||
LocalIconStyle provides LocalIconStyle.current.copy(tint = colors.titleIconTint),
|
||||
LocalTextStyle provides style.titleTextStyle.copy(color = colors.titleTextColor)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(style.titlePadding),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
content = titleContent
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -112,16 +158,17 @@ fun FlexiDialog(
|
||||
}
|
||||
}
|
||||
|
||||
/** Build the buttons of dialog. */
|
||||
@Composable
|
||||
fun Buttons() {
|
||||
Column(
|
||||
modifier = Modifier.padding(top = style.buttonsSpacing),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
neutralButton?.also { content ->
|
||||
neutralButton?.also { button ->
|
||||
SubcomposeRow(
|
||||
modifier = Modifier.fillMaxWidth().padding(bottom = style.buttonsSpacing),
|
||||
content = content
|
||||
content = button
|
||||
)
|
||||
}
|
||||
SubcomposeRow(
|
||||
@@ -130,10 +177,10 @@ fun FlexiDialog(
|
||||
spacingBetween = style.buttonsSpacing
|
||||
) {
|
||||
cancelButton?.invoke()
|
||||
confirmButton?.also { content ->
|
||||
confirmButton?.also { button ->
|
||||
CompositionLocalProvider(
|
||||
LocalPrimaryButton provides true,
|
||||
content = content
|
||||
content = button
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -157,16 +204,19 @@ fun FlexiDialog(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic flexi dialog for internal use.
|
||||
*/
|
||||
@Composable
|
||||
fun BasicFlexiDialog(
|
||||
private fun BasicFlexiDialog(
|
||||
visible: Boolean,
|
||||
onDismissRequest: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
animated: Boolean = true,
|
||||
boxStyle: AreaBoxStyle = AreaBox.style,
|
||||
maxWidth: Dp = DefaultMaxWidth,
|
||||
contentAlignment: Alignment = Alignment.TopStart,
|
||||
properties: DialogPropertiesWrapper = DefaultDialogProperties,
|
||||
modifier: Modifier,
|
||||
animated: Boolean,
|
||||
boxStyle: AreaBoxStyle,
|
||||
maxWidth: Dp,
|
||||
contentAlignment: Alignment,
|
||||
properties: DialogPropertiesWrapper,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val animatedAlpha by animateFloatAsState(if (visible) 1f else 0f, tween(AnimationDuration))
|
||||
@@ -205,7 +255,10 @@ fun BasicFlexiDialog(
|
||||
}
|
||||
}
|
||||
|
||||
object FlexiDialog {
|
||||
/**
|
||||
* Defaults of flexi dialog.
|
||||
*/
|
||||
object FlexiDialogDefaults {
|
||||
val colors: FlexiDialogColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
@@ -220,13 +273,14 @@ object FlexiDialog {
|
||||
@ReadOnlyComposable
|
||||
private fun defaultFlexiDialogColors() = FlexiDialogColors(
|
||||
titleTextColor = LocalColors.current.textPrimary,
|
||||
titleIconTint = LocalColors.current.textPrimary,
|
||||
contentTextColor = LocalColors.current.textSecondary
|
||||
)
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
private fun defaultFlexiDialogStyle() = FlexiDialogStyle(
|
||||
boxStyle = AreaBox.style.copy(padding = ComponentPadding(LocalSizes.current.spacingSecondary)),
|
||||
boxStyle = AreaBoxDefaults.style.copy(padding = ComponentPadding(LocalSizes.current.spacingSecondary)),
|
||||
titleTextStyle = LocalTypography.current.titleSecondary,
|
||||
contentTextStyle = LocalTypography.current.primary,
|
||||
maxWidth = DefaultMaxWidth,
|
||||
|
@@ -26,6 +26,10 @@ package com.highcapable.flexiui
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
|
||||
/**
|
||||
* Whether dynamic color is available for current system.
|
||||
* @return [Boolean]
|
||||
*/
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
actual fun isDynamicColorAvailable() = false
|
||||
|
@@ -26,7 +26,7 @@ package com.highcapable.flexiui
|
||||
import androidx.compose.foundation.LocalContextMenuRepresentation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import com.highcapable.flexiui.component.DesktopContextMenu
|
||||
import com.highcapable.flexiui.component.DesktopContextMenuDefaults
|
||||
import com.highcapable.flexiui.component.DesktopContextMenuRepresentation
|
||||
import com.highcapable.flexiui.component.LocalContextMenuColors
|
||||
import com.highcapable.flexiui.component.LocalContextMenuStyle
|
||||
@@ -42,8 +42,8 @@ internal actual fun FlexiThemeContent(content: @Composable () -> Unit) {
|
||||
CompositionLocalProvider(
|
||||
LocalContextMenuRepresentation provides
|
||||
DesktopContextMenuRepresentation(
|
||||
colors = DesktopContextMenu.colors,
|
||||
style = DesktopContextMenu.style
|
||||
colors = DesktopContextMenuDefaults.colors,
|
||||
style = DesktopContextMenuDefaults.style
|
||||
),
|
||||
content = content
|
||||
)
|
||||
|
@@ -68,12 +68,22 @@ import com.highcapable.flexiui.LocalSizes
|
||||
import com.highcapable.flexiui.interaction.rippleClickable
|
||||
import java.awt.event.KeyEvent
|
||||
|
||||
/**
|
||||
* Colors defines for the context menu.
|
||||
* @param contentColor the content color, usually for the text color.
|
||||
* @param borderColor the border color.
|
||||
*/
|
||||
@Immutable
|
||||
data class ContextMenuColors(
|
||||
val contentColor: Color,
|
||||
val borderColor: Color
|
||||
)
|
||||
|
||||
/**
|
||||
* Style defines for the context menu.
|
||||
* @param contentStyle the content style of area box.
|
||||
* @param borderStyle the border style of area box.
|
||||
*/
|
||||
@Immutable
|
||||
data class ContextMenuStyle(
|
||||
val contentStyle: AreaBoxStyle?,
|
||||
@@ -172,7 +182,10 @@ private fun Modifier.onHover(onHover: (Boolean) -> Unit) = pointerInput(Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
object DesktopContextMenu {
|
||||
/**
|
||||
* Defaults of context menu.
|
||||
*/
|
||||
object DesktopContextMenuDefaults {
|
||||
val colors: ContextMenuColors
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
@@ -183,6 +196,10 @@ object DesktopContextMenu {
|
||||
get() = LocalContextMenuStyle.current
|
||||
}
|
||||
|
||||
/**
|
||||
* CompositionLocal containing the preferred [ContextMenuColors]
|
||||
* that will be used by context menu by default.
|
||||
*/
|
||||
val LocalContextMenuColors = compositionLocalOf {
|
||||
ContextMenuColors(
|
||||
borderColor = Color.Unspecified,
|
||||
@@ -190,6 +207,10 @@ val LocalContextMenuColors = compositionLocalOf {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* CompositionLocal containing the preferred [ContextMenuStyle]
|
||||
* that will be used by context menu by default.
|
||||
*/
|
||||
val LocalContextMenuStyle = compositionLocalOf {
|
||||
ContextMenuStyle(
|
||||
contentStyle = null,
|
||||
@@ -207,11 +228,11 @@ internal fun defaultContextMenuColors() = ContextMenuColors(
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
internal fun defaultContextMenuStyle() = ContextMenuStyle(
|
||||
contentStyle = LocalContextMenuStyle.current.contentStyle ?: AreaBox.style.copy(
|
||||
contentStyle = LocalContextMenuStyle.current.contentStyle ?: AreaBoxDefaults.style.copy(
|
||||
padding = ComponentPadding(horizontal = DefaultMenuContentPadding),
|
||||
shape = LocalShapes.current.secondary
|
||||
),
|
||||
borderStyle = LocalContextMenuStyle.current.borderStyle ?: AreaBox.style.copy(
|
||||
borderStyle = LocalContextMenuStyle.current.borderStyle ?: AreaBoxDefaults.style.copy(
|
||||
padding = ComponentPadding(LocalSizes.current.spacingTertiary),
|
||||
shadowSize = LocalSizes.current.zoomSizeTertiary,
|
||||
shape = LocalShapes.current.primary
|
||||
|
@@ -26,6 +26,10 @@ package com.highcapable.flexiui
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
|
||||
/**
|
||||
* Whether dynamic color is available for current system.
|
||||
* @return [Boolean]
|
||||
*/
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
actual fun isDynamicColorAvailable() = false
|
||||
|
@@ -23,4 +23,7 @@
|
||||
|
||||
package com.highcapable.flexiui.resources
|
||||
|
||||
/**
|
||||
* The default icon resources for Flexi UI.
|
||||
*/
|
||||
object Icons
|
Reference in New Issue
Block a user