diff --git a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/ActionBar.kt b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/ActionBar.kt index d5ce493..0f7d374 100644 --- a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/ActionBar.kt +++ b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/ActionBar.kt @@ -261,7 +261,7 @@ class BasicActionBar internal constructor( content: @Composable () -> Unit ) { CompositionLocalProvider( - LocalIconTint provides color, + LocalIconStyle provides LocalIconStyle.current.copy(tint = color), LocalTextStyle provides LocalTextStyle.current.merge(textStyle ?: LocalTextStyle.current).copy(color = color), content = content ) diff --git a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Button.kt b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Button.kt index 080a47e..d5102cf 100644 --- a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Button.kt +++ b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Button.kt @@ -101,7 +101,7 @@ fun Button( ) ) { CompositionLocalProvider( - LocalIconTint provides colors.contentColor, + LocalIconStyle provides LocalIconStyle.current.copy(tint = colors.contentColor), LocalTextStyle provides localTextStyle, LocalProgressIndicatorColors provides localProgressIndicatorColors ) { @@ -141,7 +141,12 @@ fun IconButton( onClick = onClick ).padding(style.padding), contentAlignment = Alignment.Center, - ) { CompositionLocalProvider(LocalIconTint provides colors.contentColor, content = content) } + ) { + CompositionLocalProvider( + LocalIconStyle provides LocalIconStyle.current.copy(tint = colors.contentColor), + content = content + ) + } } @Composable @@ -170,7 +175,12 @@ fun IconToggleButton( interactionSource = interactionSource ).padding(style.padding), contentAlignment = Alignment.Center - ) { CompositionLocalProvider(LocalIconTint provides colors.contentColor, content = content) } + ) { + CompositionLocalProvider( + LocalIconStyle provides LocalIconStyle.current.copy(tint = colors.contentColor), + content = content + ) + } } private fun Modifier.button( @@ -252,7 +262,7 @@ private fun defaultButtonRippleStyle() = @Composable @ReadOnlyComposable private fun defaultIconButtonColors() = ButtonColors( - contentColor = LocalIconTint.current.orElse() ?: LocalColors.current.themePrimary, + contentColor = LocalIconStyle.current.tint.orElse() ?: LocalColors.current.themePrimary, backgroundColor = Color.Transparent ) diff --git a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/CheckBox.kt b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/CheckBox.kt index 349cf5d..d4c733b 100644 --- a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/CheckBox.kt +++ b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/CheckBox.kt @@ -119,7 +119,7 @@ fun CheckBox( scaleY = animatedContentLayer ), imageVector = Icons.CheckMark, - tint = colors.contentColor + style = Icon.style.copy(tint = colors.contentColor) ) } content?.also { content -> diff --git a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Dropdown.kt b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Dropdown.kt index f093ccd..00ad3c2 100644 --- a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Dropdown.kt +++ b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Dropdown.kt @@ -221,7 +221,7 @@ fun DropdownList( rotationZ = animatedDirection }.size(style.endIconSize), imageVector = Icons.Dropdown, - tint = animatedEndIconTint + style = Icon.style.copy(tint = animatedEndIconTint) ) } DropdownMenu( @@ -345,7 +345,7 @@ fun DropdownMenuItem( verticalAlignment = Alignment.CenterVertically ) { CompositionLocalProvider( - LocalIconTint provides currentColor, + LocalIconStyle provides LocalIconStyle.current.copy(tint = currentColor), LocalTextStyle provides LocalTextStyle.current.copy(color = currentColor) ) { content() } } diff --git a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Icon.kt b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Icon.kt index f4de9da..46278cd 100644 --- a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Icon.kt +++ b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Icon.kt @@ -26,6 +26,7 @@ package com.highcapable.flexiui.component import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.Modifier @@ -34,26 +35,37 @@ import androidx.compose.ui.draw.paint import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.isUnspecified import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.toolingGraphicsLayer import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.debugInspectorInfo import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.isSpecified import com.highcapable.flexiui.LocalSizes +import com.highcapable.flexiui.extension.orElse + +@Immutable +data class IconStyle( + val size: Dp, + val tint: Color +) @Composable fun Icon( imageVector: ImageVector, contentDescription: String? = null, modifier: Modifier = Modifier, - tint: Color = LocalIconTint.current + style: IconStyle = Icon.style ) { val painter = rememberVectorPainter(imageVector) - Icon(painter, contentDescription, modifier, tint) + Icon(painter, contentDescription, modifier, style) } @Composable @@ -61,10 +73,10 @@ fun Icon( painter: Painter, contentDescription: String? = null, modifier: Modifier = Modifier, - tint: Color = LocalIconTint.current + style: IconStyle = Icon.style ) { // TODO: b/149735981 semantics for content description - val colorFilter = if (tint == Color.Unspecified) null else ColorFilter.tint(tint) + val colorFilter = if (style.tint.isUnspecified) null else ColorFilter.tint(style.tint) val semantics = if (contentDescription != null) Modifier.semantics { this.contentDescription = contentDescription @@ -73,7 +85,7 @@ fun Icon( else Modifier Box( modifier = modifier.toolingGraphicsLayer() - .defaultSizeFor(painter) + .defaultSizeFor(style, painter) .paint( painter, colorFilter = colorFilter, @@ -83,16 +95,39 @@ fun Icon( ) } -internal val LocalIconTint = compositionLocalOf { Color.Unspecified } - -private fun Modifier.defaultSizeFor(painter: Painter) = composed { - then( - if (painter.intrinsicSize == Size.Unspecified || painter.intrinsicSize.isInfinite()) - Modifier.size(defaultIconSize()) - else Modifier - ) +private fun Modifier.defaultSizeFor( + style: IconStyle, + painter: Painter +) = composed( + inspectorInfo = debugInspectorInfo { + name = "defaultSizeFor" + properties["style"] = style + properties["painter"] = painter + } +) { + then(when { + style.size.isSpecified || + painter.intrinsicSize == Size.Unspecified || + painter.intrinsicSize.isInfinite() -> + Modifier.size(style.size.orElse() ?: defaultIconSize()) + else -> Modifier + }) } +object Icon { + val style: IconStyle + @Composable + @ReadOnlyComposable + get() = LocalIconStyle.current +} + +internal val LocalIconStyle = compositionLocalOf { DefaultIconStyle } + +private val DefaultIconStyle = IconStyle( + size = Dp.Unspecified, + tint = Color.Unspecified +) + @Composable @ReadOnlyComposable private fun defaultIconSize() = LocalSizes.current.iconSizePrimary diff --git a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Navigation.kt b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Navigation.kt index f76357e..77c7212 100644 --- a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Navigation.kt +++ b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Navigation.kt @@ -135,7 +135,8 @@ fun NavigationItem( val currentContentShape = contentShape ?: LocalNavigationContentShape.current ?: Navigation.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 currentContentStyle = LocalTextStyle.current.copy(color = animatedContentColor) + val currentIconStyle = LocalIconStyle.current.copy(tint = animatedContentColor) + val currentTextStyle = LocalTextStyle.current.copy(color = animatedContentColor) Box( modifier = Modifier.status(enabled) .clip(currentContentShape) @@ -151,8 +152,8 @@ fun NavigationItem( .padding(currentContentPadding) ) { CompositionLocalProvider( - LocalIconTint provides animatedContentColor, - LocalTextStyle provides currentContentStyle + LocalIconStyle provides currentIconStyle, + LocalTextStyle provides currentTextStyle ) { if (currentHorizontal) Row( diff --git a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Tab.kt b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Tab.kt index 163daac..63f0ec0 100644 --- a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Tab.kt +++ b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Tab.kt @@ -210,10 +210,11 @@ fun Tab( val currentContentPadding = contentPadding ?: LocalTabContentPadding.current ?: Tab.style.contentPadding val currentContentShape = contentShape ?: LocalTabContentShape.current ?: Tab.style.contentShape val contentColor by animateColorAsState(if (selected) currentSelectedContentColor else currentUnselectedContentColor) - val contentStyle = LocalTextStyle.current.copy(color = contentColor) + val contentIconStyle = LocalIconStyle.current.copy(tint = contentColor) + val contentTextStyle = LocalTextStyle.current.copy(color = contentColor) CompositionLocalProvider( - LocalIconTint provides contentColor, - LocalTextStyle provides contentStyle + LocalIconStyle provides contentIconStyle, + LocalTextStyle provides contentTextStyle ) { Row( modifier = Modifier.status(enabled) diff --git a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/TextField.kt b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/TextField.kt index 0af7a46..49637ec 100644 --- a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/TextField.kt +++ b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/TextField.kt @@ -667,9 +667,11 @@ private fun InnerDecorationBox( content: @Composable () -> Unit ) { Box(modifier = Modifier.textFieldPadding(style, fitStart = header, fitEnd = footer)) { - CompositionLocalProvider(LocalIconTint provides decorTint) { - content() - } + CompositionLocalProvider( + LocalIconStyle provides LocalIconStyle.current.copy(tint = decorTint), + LocalTextStyle provides LocalTextStyle.current.copy(color = decorTint), + content = content + ) } } @@ -683,7 +685,7 @@ private fun TextFieldDecorationBox( val animatedAlpha by animateFloatAsState(if (value.isNotEmpty()) 0f else 1f) Box(modifier = Modifier.alpha(animatedAlpha)) { CompositionLocalProvider( - LocalIconTint provides placeholderContentColor, + LocalIconStyle provides LocalIconStyle.current.copy(tint = placeholderContentColor), LocalTextStyle provides LocalTextStyle.current.copy(color = placeholderContentColor), content = placeholder )