feat(filters): быстрый выбор категории + очистка поиска
- Кнопка-«категории» (круглая, акцентная рамка, иконка SlidersHorizontal) СЛЕВА от чипа «Все» — на экранах Радио и Чарты. Открывает шторку со списком всех категорий (Радио — жанры, Чарты — стили) + поиск, чтобы не листать чипы. CategoryPicker — переиспользуемый компонент с поиском и отметкой выбранного. - SearchBar: анимированная кнопка очистки (X, scale+fade появление, haptic) при непустом запросе.
This commit is contained in:
@@ -1,17 +1,32 @@
|
||||
package com.radiola.ui.components
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.scaleIn
|
||||
import androidx.compose.animation.scaleOut
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.composables.icons.lucide.Lucide
|
||||
import com.composables.icons.lucide.Search
|
||||
import com.composables.icons.lucide.X
|
||||
import com.radiola.ui.theme.RadiolaTheme
|
||||
|
||||
@Composable
|
||||
@@ -22,6 +37,7 @@ fun SearchBar(
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val colors = RadiolaTheme.colors
|
||||
val haptics = LocalHapticFeedback.current
|
||||
TextField(
|
||||
value = query,
|
||||
onValueChange = onQueryChange,
|
||||
@@ -29,6 +45,31 @@ fun SearchBar(
|
||||
shape = RoundedCornerShape(14.dp),
|
||||
placeholder = { Text(placeholder, color = colors.textMuted) },
|
||||
leadingIcon = { Icon(Lucide.Search, contentDescription = null, tint = colors.textMuted) },
|
||||
// Кнопка «очистить» — появляется/исчезает с анимацией (scale + fade).
|
||||
trailingIcon = {
|
||||
AnimatedVisibility(
|
||||
visible = query.isNotEmpty(),
|
||||
enter = scaleIn() + fadeIn(),
|
||||
exit = scaleOut() + fadeOut()
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Lucide.X,
|
||||
contentDescription = "Очистить",
|
||||
tint = colors.textSecondary,
|
||||
modifier = Modifier
|
||||
.size(34.dp)
|
||||
.padding(7.dp)
|
||||
.clip(CircleShape)
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null
|
||||
) {
|
||||
haptics.performHapticFeedback(HapticFeedbackType.TextHandleMove)
|
||||
onQueryChange("")
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
singleLine = true,
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = colors.surface,
|
||||
|
||||
Reference in New Issue
Block a user