Updated on 2026-08-14
This commit is contained in:
parent
5da322576b
commit
c037bec366
15 changed files with 782 additions and 116 deletions
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue