Benoit Marty 2025-10-13 13:29:07 +02:00 committed by Benoit Marty
parent 3aa7966e2c
commit 868108d725

View file

@ -20,7 +20,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.SearchBar import androidx.compose.material3.SearchBar
import androidx.compose.material3.SearchBarColors import androidx.compose.material3.SearchBarColors
import androidx.compose.material3.SearchBarDefaults import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.TextFieldColors
import androidx.compose.material3.TextFieldDefaults import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
@ -45,6 +44,9 @@ import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
/**
* Ref: https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=1992-8350
*/
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun <T> SearchBar( fun <T> SearchBar(
@ -63,14 +65,12 @@ fun <T> SearchBar(
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
inactiveBarColors: SearchBarColors = ElementSearchBarDefaults.inactiveColors(), inactiveBarColors: SearchBarColors = ElementSearchBarDefaults.inactiveColors(),
activeBarColors: SearchBarColors = ElementSearchBarDefaults.activeColors(), activeBarColors: SearchBarColors = ElementSearchBarDefaults.activeColors(),
inactiveTextInputColors: TextFieldColors = ElementSearchBarDefaults.inactiveInputFieldColors(),
activeTextInputColors: TextFieldColors = ElementSearchBarDefaults.activeInputFieldColors(),
contentPrefix: @Composable ColumnScope.() -> Unit = {}, contentPrefix: @Composable ColumnScope.() -> Unit = {},
contentSuffix: @Composable ColumnScope.() -> Unit = {}, contentSuffix: @Composable ColumnScope.() -> Unit = {},
resultHandler: @Composable ColumnScope.(T) -> Unit = {}, resultHandler: @Composable ColumnScope.(T) -> Unit = {},
) { ) {
val focusManager = LocalFocusManager.current val focusManager = LocalFocusManager.current
val colors = if (active) activeBarColors else inactiveBarColors
val updatedOnQueryChange by rememberUpdatedState(onQueryChange) val updatedOnQueryChange by rememberUpdatedState(onQueryChange)
LaunchedEffect(active) { LaunchedEffect(active) {
if (!active) { if (!active) {
@ -107,28 +107,25 @@ fun <T> SearchBar(
} }
} }
} }
!active -> { !active -> {
{ {
Icon( Icon(
imageVector = CompoundIcons.Search(), imageVector = CompoundIcons.Search(),
contentDescription = stringResource(CommonStrings.action_search), contentDescription = stringResource(CommonStrings.action_search),
tint = ElementTheme.colors.iconTertiary,
) )
} }
} }
else -> null else -> null
}, },
interactionSource = interactionSource, interactionSource = interactionSource,
colors = if (active) activeTextInputColors else inactiveTextInputColors, colors = colors.inputFieldColors,
) )
}, },
expanded = active, expanded = active,
onExpandedChange = onActiveChange, onExpandedChange = onActiveChange,
modifier = modifier.padding(horizontal = if (!active) 16.dp else 0.dp), modifier = modifier.padding(horizontal = if (!active) 16.dp else 0.dp),
shape = shape, shape = shape,
colors = if (active) activeBarColors else inactiveBarColors, colors = colors,
tonalElevation = tonalElevation, tonalElevation = tonalElevation,
windowInsets = windowInsets, windowInsets = windowInsets,
content = { content = {
@ -163,35 +160,43 @@ object ElementSearchBarDefaults {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun inactiveColors() = SearchBarDefaults.colors( fun inactiveColors() = SearchBarDefaults.colors(
containerColor = ElementTheme.materialColors.surfaceVariant, containerColor = Color.Transparent,
dividerColor = ElementTheme.materialColors.outline, dividerColor = ElementTheme.colors.borderInteractivePrimary,
inputFieldColors = inactiveInputFieldColors(),
) )
@Composable @Composable
fun inactiveInputFieldColors() = TextFieldDefaults.colors( fun inactiveInputFieldColors() = TextFieldDefaults.colors(
unfocusedPlaceholderColor = ElementTheme.colors.textDisabled, unfocusedPlaceholderColor = ElementTheme.colors.textDisabled,
focusedPlaceholderColor = ElementTheme.colors.textDisabled, focusedPlaceholderColor = ElementTheme.colors.textDisabled,
unfocusedLeadingIconColor = ElementTheme.materialColors.primary, unfocusedTrailingIconColor = ElementTheme.colors.iconDisabled,
focusedLeadingIconColor = ElementTheme.materialColors.primary, focusedTrailingIconColor = ElementTheme.colors.iconDisabled,
unfocusedTrailingIconColor = ElementTheme.materialColors.primary, focusedContainerColor = Color.Transparent,
focusedTrailingIconColor = ElementTheme.materialColors.primary, unfocusedContainerColor = Color.Transparent,
disabledContainerColor = Color.Transparent,
errorContainerColor = Color.Transparent,
) )
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun activeColors() = SearchBarDefaults.colors( fun activeColors() = SearchBarDefaults.colors(
containerColor = Color.Transparent, containerColor = Color.Transparent,
dividerColor = ElementTheme.materialColors.outline, dividerColor = ElementTheme.colors.borderInteractivePrimary,
inputFieldColors = activeInputFieldColors(),
) )
@Composable @Composable
fun activeInputFieldColors() = TextFieldDefaults.colors( fun activeInputFieldColors() = TextFieldDefaults.colors(
unfocusedPlaceholderColor = ElementTheme.colors.textDisabled, unfocusedPlaceholderColor = ElementTheme.colors.textSecondary,
focusedPlaceholderColor = ElementTheme.colors.textDisabled, focusedPlaceholderColor = ElementTheme.colors.textSecondary,
unfocusedLeadingIconColor = ElementTheme.materialColors.primary, unfocusedLeadingIconColor = ElementTheme.colors.iconPrimary,
focusedLeadingIconColor = ElementTheme.materialColors.primary, focusedLeadingIconColor = ElementTheme.colors.iconPrimary,
unfocusedTrailingIconColor = ElementTheme.materialColors.primary, unfocusedTrailingIconColor = ElementTheme.colors.iconTertiary,
focusedTrailingIconColor = ElementTheme.materialColors.primary, focusedTrailingIconColor = ElementTheme.colors.iconTertiary,
focusedContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent,
disabledContainerColor = Color.Transparent,
errorContainerColor = Color.Transparent,
) )
} }