Updated on 2026-08-14

This commit is contained in:
Tangem 2026-03-17 20:20:52 +05:00
parent 5da322576b
commit c037bec366
15 changed files with 782 additions and 116 deletions

View file

@ -1,6 +1,7 @@
package com.tangem.feature.tester.presentation.storybook.entity
import com.tangem.core.ui.ds.badge.TangemBadgeColor
import com.tangem.core.ui.ds.field.search.TangemFieldShape
import com.tangem.core.ui.ds.message.TangemMessageEffect
internal sealed interface StoryBookPage
@ -53,4 +54,9 @@ internal data class TangemContextMenuStory(
internal data class TangemHeaderRowStory(
val isBalanceHidden: Boolean,
val onBalanceHiddenToggle: () -> Unit,
) : StoryBookPage
internal data class TangemSearchFieldStory(
val selectedShape: TangemFieldShape,
val onShapeChange: (TangemFieldShape) -> Unit,
) : StoryBookPage

View file

@ -0,0 +1,18 @@
package com.tangem.feature.tester.presentation.storybook.page.searchfield
import com.tangem.core.ui.ds.field.search.TangemFieldShape
import com.tangem.feature.tester.presentation.storybook.entity.TangemSearchFieldStory
import com.tangem.feature.tester.presentation.storybook.viewmodel.StateUpdater
import com.tangem.feature.tester.presentation.storybook.viewmodel.storyPageFactory
internal fun StateUpdater<TangemSearchFieldStory>.build(): TangemSearchFieldStory {
return TangemSearchFieldStory(
selectedShape = TangemFieldShape.RoundedCorners,
onShapeChange = { shape ->
updateStory { it.copy(selectedShape = shape) }
},
)
}
internal val tangemSearchFieldStoryFactory
get() = storyPageFactory(StateUpdater<TangemSearchFieldStory>::build)

View file

@ -0,0 +1,151 @@
@file:Suppress("MagicNumber", "LongMethod")
package com.tangem.feature.tester.presentation.storybook.page.searchfield
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.fields.entity.SearchBarUM
import com.tangem.core.ui.ds.field.search.TangemFieldShape
import com.tangem.core.ui.ds.field.search.TangemSearchField
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.tester.presentation.storybook.entity.TangemSearchFieldStory
@Composable
internal fun TangemSearchFieldStory(state: TangemSearchFieldStory, modifier: Modifier = Modifier) {
var query by remember { mutableStateOf("") }
var isActive by remember { mutableStateOf(false) }
LazyColumn(
contentPadding = PaddingValues(bottom = 16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = modifier
.fillMaxSize()
.statusBarsPadding()
.background(TangemTheme.colors2.surface.level1),
) {
stickyHeader("shape_toggle") {
ShapeToggle(
selected = state.selectedShape,
onSelect = state.onShapeChange,
modifier = Modifier
.fillMaxWidth()
.background(TangemTheme.colors2.surface.level1)
.padding(horizontal = 16.dp, vertical = 8.dp),
)
}
item("empty") {
VariantSection(label = "Empty") {
TangemSearchField(
state = SearchBarUM(
placeholderText = resourceReference(R.string.manage_tokens_search_placeholder),
query = query,
onQueryChange = { query = it },
isActive = isActive,
onActiveChange = { isActive = it },
onClearClick = { query = "" },
),
shape = state.selectedShape,
)
}
}
item("prefilled") {
VariantSection(label = "Pre-filled") {
var prefilledQuery by remember { mutableStateOf("Bitcoin") }
var isPrefilledActive by remember { mutableStateOf(false) }
TangemSearchField(
state = SearchBarUM(
placeholderText = resourceReference(R.string.manage_tokens_search_placeholder),
query = prefilledQuery,
onQueryChange = { prefilledQuery = it },
isActive = isPrefilledActive,
onActiveChange = { isPrefilledActive = it },
onClearClick = { prefilledQuery = "" },
),
shape = state.selectedShape,
)
}
}
}
}
@Composable
private fun ShapeToggle(
selected: TangemFieldShape,
onSelect: (TangemFieldShape) -> Unit,
modifier: Modifier = Modifier,
) {
val shape = RoundedCornerShape(50)
Row(
modifier = modifier
.clip(shape)
.background(TangemTheme.colors2.surface.level2)
.border(
width = 1.dp,
color = TangemTheme.colors2.border.neutral.secondary,
shape = shape,
)
.padding(4.dp),
horizontalArrangement = Arrangement.spacedBy(4.dp),
) {
TangemFieldShape.entries.forEach { fieldShape ->
ShapeChip(
label = fieldShape.name,
selected = fieldShape == selected,
onClick = { onSelect(fieldShape) },
modifier = Modifier.weight(1f),
)
}
}
}
@Composable
private fun ShapeChip(label: String, selected: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) {
val chipShape = RoundedCornerShape(50)
Box(
contentAlignment = Alignment.Center,
modifier = modifier
.clip(chipShape)
.background(
if (selected) TangemTheme.colors2.surface.level3 else TangemTheme.colors2.surface.level2,
)
.clickable(onClick = onClick)
.padding(vertical = 8.dp, horizontal = 4.dp),
) {
Text(
text = label,
style = TangemTheme.typography.caption2,
color = if (selected) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.secondary,
)
}
}
@Composable
private fun VariantSection(label: String, content: @Composable ColumnScope.() -> Unit) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
) {
Text(
text = label,
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.secondary,
)
content()
}
}

View file

@ -23,6 +23,7 @@ import com.tangem.feature.tester.presentation.storybook.page.contextmenu.tangemC
import com.tangem.feature.tester.presentation.storybook.page.headerrow.tangemHeaderRowStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.message.tangemMessageStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.opportunities.opportunitiesBGStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.searchfield.tangemSearchFieldStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.tabs.tangemSegmentedPickerStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.tokenrow.tangemTokenRowStoryFactory
@ -39,6 +40,7 @@ private fun buildStories() = listOf(
StoryItem(title = "🪙 Token Row", factory = tangemTokenRowStoryFactory),
StoryItem(title = "📑 Header Row", factory = tangemHeaderRowStoryFactory),
StoryItem(title = "📋 Context Menu", factory = tangemContextMenuStoryFactory),
StoryItem(title = "🔍 Search Field", factory = tangemSearchFieldStoryFactory),
)
@Composable

View file

@ -14,6 +14,7 @@ import com.tangem.feature.tester.presentation.storybook.entity.TangemCheckboxSto
import com.tangem.feature.tester.presentation.storybook.entity.TangemHeaderRowStory
import com.tangem.feature.tester.presentation.storybook.entity.TangemContextMenuStory
import com.tangem.feature.tester.presentation.storybook.entity.TangemMessageStory
import com.tangem.feature.tester.presentation.storybook.entity.TangemSearchFieldStory
import com.tangem.feature.tester.presentation.storybook.entity.TangemSegmentedPickerStory
import com.tangem.feature.tester.presentation.storybook.entity.TangemTokenRowStory
import com.tangem.feature.tester.presentation.storybook.page.background.NorthernLightsStory
@ -26,6 +27,7 @@ import com.tangem.feature.tester.presentation.storybook.page.tabs.TangemSegmente
import com.tangem.feature.tester.presentation.storybook.page.tokenrow.TangemTokenRowStory
import com.tangem.feature.tester.presentation.storybook.page.headerrow.TangemHeaderRowStory
import com.tangem.feature.tester.presentation.storybook.page.contextmenu.TangemContextMenuStory
import com.tangem.feature.tester.presentation.storybook.page.searchfield.TangemSearchFieldStory
@Composable
internal fun StoryBookScreen(state: StoryBookUM, modifier: Modifier = Modifier) {
@ -48,6 +50,7 @@ internal fun StoryBookScreen(state: StoryBookUM, modifier: Modifier = Modifier)
is TangemTokenRowStory -> TangemTokenRowStory(state = storyState)
is TangemHeaderRowStory -> TangemHeaderRowStory(state = storyState)
is TangemContextMenuStory -> TangemContextMenuStory(state = storyState)
is TangemSearchFieldStory -> TangemSearchFieldStory(state = storyState)
}
}
}