Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-03 12:12:37 +03:00
parent 80c206e13b
commit df4186cca0
7 changed files with 672 additions and 2 deletions

View file

@ -214,12 +214,15 @@ private inline fun ProvideButtonRippleConfiguration(crossinline content: @Compos
@Composable
private fun TangemButtonIcon(tangemIconUM: TangemIconUM?, isVisible: Boolean, size: TangemButtonSize) {
val wrappedIconUM = rememberLastNonNull(tangemIconUM)
AnimatedVisibility(
visible = isVisible,
modifier = Modifier.size(size = size.toContentSize()),
) {
val wrappedIconUM = remember(tangemIconUM) { requireNotNull(tangemIconUM) }
TangemIcon(tangemIconUM = wrappedIconUM)
wrappedIconUM?.let {
TangemIcon(tangemIconUM = it)
}
}
}

View file

@ -0,0 +1,325 @@
package com.tangem.core.ui.ds2.search
import android.content.res.Configuration
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.shrinkHorizontally
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.PlatformTextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.ds2.button.TangemButton
import com.tangem.core.ui.ds2.surface.TangemSurface
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_cross_20
import com.tangem.core.ui.res.generated.icons.ic_cross_circle_20_filled
import com.tangem.core.ui.res.generated.icons.ic_search_20
/**
* Search component (DS V3)
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=3953-249&m=dev)
*
* @param state Hoisted state holding the query, active flag, placeholder, and callbacks.
* When [TangemSearch.State.onCloseClick] is `null`, the trailing close button is omitted.
* @param modifier Modifier applied to the outer row container.
* @param focusRequester Focus requester wired to the text field. Pass a hoisted instance to
* programmatically focus the field from the caller (e.g., on screen entry). Tapping anywhere on
* the surface also invokes [FocusRequester.requestFocus] on this instance.
*/
@Composable
fun TangemSearch(
state: TangemSearch.State,
modifier: Modifier = Modifier,
focusRequester: FocusRequester = remember { FocusRequester() },
) {
val openingEasing = CubicBezierEasing(a = 0.8f, b = 0f, c = 0.2f, d = 1f)
val closingEasing = CubicBezierEasing(a = 0.8f, b = 0f, c = 0.8f, d = 1f)
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
) {
TangemSurface(
modifier = Modifier
.weight(1f)
.heightIn(min = TangemTheme.dimens3.size.s550),
isMaterial = true,
shape = CircleShape,
onClick = focusRequester::requestFocus,
) {
SearchField(state = state, focusRequester = focusRequester)
}
AnimatedVisibility(
visible = state.onCloseClick != null && (state.isActive || state.query.isNotEmpty()),
enter = expandHorizontally(animationSpec = tween(durationMillis = 150, easing = openingEasing)) +
fadeIn(animationSpec = tween(durationMillis = 150, delayMillis = 150, easing = openingEasing)) +
scaleIn(animationSpec = tween(durationMillis = 150, delayMillis = 150, easing = openingEasing)),
exit = fadeOut(animationSpec = tween(durationMillis = 150, easing = closingEasing)) +
scaleOut(animationSpec = tween(durationMillis = 150, easing = closingEasing)) +
shrinkHorizontally(animationSpec = tween(durationMillis = 150, easing = closingEasing)),
) {
CloseButton(onClick = state.onCloseClick ?: {})
}
}
}
object TangemSearch {
@Immutable
data class State(
val placeholderText: TextReference,
val query: String,
val onQueryChange: (String) -> Unit,
val isActive: Boolean,
val onActiveChange: (Boolean) -> Unit,
val onClearClick: () -> Unit = { },
val onCloseClick: (() -> Unit)? = null,
)
}
@Composable
private fun SearchField(state: TangemSearch.State, focusRequester: FocusRequester) {
Row(verticalAlignment = Alignment.CenterVertically) {
Row(
modifier = Modifier
.weight(1f)
.padding(
start = TangemTheme.dimens3.spacing.s150,
top = TangemTheme.dimens3.spacing.s150,
bottom = TangemTheme.dimens3.spacing.s150,
),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
modifier = Modifier.padding(end = TangemTheme.dimens3.spacing.s100),
imageVector = Icons.ic_search_20,
tint = TangemTheme.colors3.icon.primary,
contentDescription = null,
)
QueryTextField(state = state, focusRequester = focusRequester)
}
AnimatedVisibility(
visible = state.query.isNotEmpty(),
enter = fadeIn(),
exit = fadeOut(),
) {
ClearButton(
onClick = {
state.onQueryChange("")
state.onClearClick()
},
)
}
}
}
@Composable
private fun QueryTextField(state: TangemSearch.State, focusRequester: FocusRequester) {
val keyboardController = LocalSoftwareKeyboardController.current
val focusManager = LocalFocusManager.current
// Initial composition reports isFocused = false. Without this guard the field would
// clobber a parent-supplied `state.isActive = true` on the first frame.
var isInitialComposition by remember { mutableStateOf(true) }
LaunchedEffect(Unit) { isInitialComposition = false }
val placeholder = state.placeholderText.resolveReference()
val sharedTextStyle = TangemTheme.typography3.body.medium.copy(
platformStyle = PlatformTextStyle(includeFontPadding = false),
)
BasicTextField(
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester)
.semantics { contentDescription = placeholder }
.onFocusChanged { focusState ->
if (!isInitialComposition) {
state.onActiveChange(focusState.isFocused)
}
},
value = state.query,
onValueChange = state.onQueryChange,
singleLine = true,
textStyle = sharedTextStyle.copy(color = TangemTheme.colors3.text.primary),
cursorBrush = SolidColor(TangemTheme.colors3.icon.brand),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Search,
),
keyboardActions = KeyboardActions(
onSearch = {
keyboardController?.hide()
focusManager.clearFocus()
},
),
decorationBox = { innerTextField ->
Box {
if (state.query.isEmpty()) {
Text(
modifier = Modifier.padding(end = TangemTheme.dimens3.spacing.s250),
text = placeholder,
style = sharedTextStyle,
color = TangemTheme.colors3.text.secondary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
innerTextField()
}
},
)
}
@Composable
private fun ClearButton(onClick: () -> Unit) {
TangemButton(
modifier = Modifier.padding(end = TangemTheme.dimens3.spacing.s050),
size = TangemButton.Size.X9,
variant = TangemButton.Variant.Ghost,
iconStart = TangemIconUM.Icon(Icons.ic_cross_circle_20_filled),
onClick = onClick,
)
}
@Composable
private fun CloseButton(onClick: () -> Unit) {
val keyboardController = LocalSoftwareKeyboardController.current
val focusManager = LocalFocusManager.current
TangemButton(
modifier = Modifier.padding(start = TangemTheme.dimens3.spacing.s100),
size = TangemButton.Size.X11,
variant = TangemButton.Variant.Material,
iconStart = TangemIconUM.Icon(Icons.ic_cross_20),
onClick = {
keyboardController?.hide()
focusManager.clearFocus()
onClick()
},
)
}
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun Preview(@PreviewParameter(TangemSearchStateProvider::class) state: TangemSearch.State) {
TangemThemePreviewRedesign {
Box(modifier = Modifier.background(TangemTheme.colors3.bg.secondary)) {
TangemSearch(
state = state,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
)
}
}
}
private class TangemSearchStateProvider : CollectionPreviewParameterProvider<TangemSearch.State>(
collection = listOf(
// Idle: empty + inactive — no clear, no close.
TangemSearch.State(
placeholderText = stringReference("Search"),
query = "",
onQueryChange = {},
isActive = false,
onActiveChange = {},
onCloseClick = {},
),
// Focused empty: active + empty — close visible, clear hidden.
TangemSearch.State(
placeholderText = stringReference("Search"),
query = "",
onQueryChange = {},
isActive = true,
onActiveChange = {},
onCloseClick = {},
),
// Typing: active + query — clear and close both visible.
TangemSearch.State(
placeholderText = stringReference("Search"),
query = "Bitcoin",
onQueryChange = {},
isActive = true,
onActiveChange = {},
onClearClick = {},
onCloseClick = {},
),
// Filled but blurred: query persists without focus — close stays visible.
TangemSearch.State(
placeholderText = stringReference("Search"),
query = "Ethereum",
onQueryChange = {},
isActive = false,
onActiveChange = {},
onClearClick = {},
onCloseClick = {},
),
// Embedded variant: no close affordance at all (onCloseClick = null).
TangemSearch.State(
placeholderText = stringReference("Filter tokens"),
query = "USDT",
onQueryChange = {},
isActive = true,
onActiveChange = {},
onClearClick = {},
onCloseClick = null,
),
// Long query that exercises clipping inside the surface.
TangemSearch.State(
placeholderText = stringReference("Search"),
query = "A very long search query that should clip nicely",
onQueryChange = {},
isActive = true,
onActiveChange = {},
onClearClick = {},
onCloseClick = {},
),
),
)

View file

@ -291,6 +291,33 @@ internal data class TangemTopNavigationStory(
}
}
@Suppress("BooleanPropertyNaming")
internal data class TangemSearchStory(
val background: Background,
val placeholder: Placeholder,
val hasCloseButton: Boolean,
val onBackgroundChange: (Background) -> Unit,
val onPlaceholderChange: (Placeholder) -> Unit,
val onCloseButtonToggle: () -> Unit,
) : DsStoryBookPage {
/** Backdrop the search preview is rendered on top of. */
enum class Background(val label: String) {
Rainbow("rainbow"),
BgPrimary("bg.primary"),
BgSecondary("bg.secondary"),
BgBrand("bg.brand"),
BgInverse("bg.inverse"),
}
/** Placeholder length variants — short typical label vs. long string to test layout. */
enum class Placeholder(val label: String, val text: String) {
Short("short", "Search"),
Medium("medium", "Filter tokens"),
Long("long", "Search by name, symbol or contract address"),
}
}
internal data class TangemBadgeV2Story(
val variant: TangemBadge.Variant,
val status: TangemBadge.Status,

View file

@ -20,6 +20,7 @@ import com.tangem.feature.tester.presentation.storybook.page.ds.button.tangemBut
import com.tangem.feature.tester.presentation.storybook.page.ds.fade.tangemFadeStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.ds.loader.tangemLoaderStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.ds.row.tangemRowStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.ds.search.tangemSearchStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.ds.shimmer.tangemShimmerStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.ds.topnavigation.tangemTopNavigationStoryFactory
@ -30,6 +31,7 @@ private fun buildDsStories() = listOf(
DsStoryItem(title = "🔘 TangemButton", factory = tangemButtonStoryFactory),
DsStoryItem(title = "🏷️ TangemBadge", factory = tangemBadgeV2StoryFactory),
DsStoryItem(title = "📋 TangemRow", factory = tangemRowStoryFactory),
DsStoryItem(title = "🔎 TangemSearch", factory = tangemSearchStoryFactory),
DsStoryItem(title = "✨ TangemShimmer", factory = tangemShimmerStoryFactory),
DsStoryItem(title = "🌫️ TangemFade", factory = tangemFadeStoryFactory),
DsStoryItem(title = "🧭 TangemTopNavigation", factory = tangemTopNavigationStoryFactory),

View file

@ -0,0 +1,25 @@
package com.tangem.feature.tester.presentation.storybook.page.ds.search
import com.tangem.feature.tester.presentation.storybook.entity.TangemSearchStory
import com.tangem.feature.tester.presentation.storybook.viewmodel.StateUpdater
import com.tangem.feature.tester.presentation.storybook.viewmodel.storyPageFactory
internal fun StateUpdater<TangemSearchStory>.build(): TangemSearchStory {
return TangemSearchStory(
background = TangemSearchStory.Background.BgSecondary,
placeholder = TangemSearchStory.Placeholder.Short,
hasCloseButton = true,
onBackgroundChange = { background ->
updateStory { it.copy(background = background) }
},
onPlaceholderChange = { placeholder ->
updateStory { it.copy(placeholder = placeholder) }
},
onCloseButtonToggle = {
updateStory { it.copy(hasCloseButton = !it.hasCloseButton) }
},
)
}
internal val tangemSearchStoryFactory
get() = storyPageFactory(StateUpdater<TangemSearchStory>::build)

View file

@ -0,0 +1,286 @@
@file:Suppress("MagicNumber")
package com.tangem.feature.tester.presentation.storybook.page.ds.search
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.TileMode
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.ds2.search.TangemSearch
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.tester.presentation.storybook.entity.TangemSearchStory
import com.tangem.feature.tester.presentation.storybook.entity.TangemSearchStory.Background
import com.tangem.feature.tester.presentation.storybook.entity.TangemSearchStory.Placeholder
@Composable
internal fun TangemSearchStory(state: TangemSearchStory, modifier: Modifier = Modifier) {
Column(
modifier = modifier
.fillMaxSize()
.background(TangemTheme.colors.background.primary)
.padding(vertical = 16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
ComponentPreview(state = state)
Column(
modifier = Modifier.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
BackgroundSelector(selected = state.background, onSelect = state.onBackgroundChange)
PlaceholderSelector(selected = state.placeholder, onSelect = state.onPlaceholderChange)
Toggles(state = state)
}
}
}
@Composable
private fun ComponentPreview(state: TangemSearchStory) {
var query by remember { mutableStateOf("") }
var isActive by remember { mutableStateOf(false) }
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
.clip(RoundedCornerShape(16.dp)),
) {
PreviewBackground(background = state.background, modifier = Modifier.matchParentSize())
TangemSearch(
state = TangemSearch.State(
placeholderText = stringReference(state.placeholder.text),
query = query,
onQueryChange = { query = it },
isActive = isActive,
onActiveChange = { isActive = it },
onClearClick = { query = "" },
// Close handles keyboard + focus internally; parent just clears the text.
onCloseClick = if (state.hasCloseButton) {
{ query = "" }
} else {
null
},
),
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
)
}
}
@Composable
private fun PreviewBackground(background: Background, modifier: Modifier = Modifier) {
when (background) {
Background.Rainbow -> BlurTestBackground(modifier = modifier)
Background.BgPrimary -> Box(modifier.background(TangemTheme.colors3.bg.primary))
Background.BgSecondary -> Box(modifier.background(TangemTheme.colors3.bg.secondary))
Background.BgBrand -> Box(modifier.background(TangemTheme.colors3.bg.brand))
Background.BgInverse -> Box(modifier.background(TangemTheme.colors3.bg.inverse))
}
}
@Composable
private fun BlurTestBackground(modifier: Modifier = Modifier) {
val bands = remember {
listOf(
Color(0xFFFF1744), // red
Color(0xFFFF9100), // orange
Color(0xFFFFEA00), // yellow
Color(0xFF00E676), // green
Color(0xFF00B8D4), // cyan
Color(0xFF2962FF), // blue
Color(0xFFD500F9), // magenta
)
}
val stops = remember(bands) {
buildList {
bands.forEachIndexed { index, color ->
val start = index.toFloat() / bands.size
val end = (index + 1).toFloat() / bands.size
add(start to color)
add(end to color)
}
}.toTypedArray()
}
val tilePx = with(LocalDensity.current) { 320.dp.toPx() }
val transition = rememberInfiniteTransition(label = "blur-bg")
val offset by transition.animateFloat(
initialValue = 0f,
targetValue = tilePx,
animationSpec = infiniteRepeatable(
animation = tween(durationMillis = 4_000, easing = LinearEasing),
repeatMode = RepeatMode.Restart,
),
label = "blur-bg-offset",
)
Box(
modifier = modifier.background(
brush = Brush.linearGradient(
colorStops = stops,
start = Offset(offset, 0f),
end = Offset(offset + tilePx, 0f),
tileMode = TileMode.Repeated,
),
),
)
}
@Composable
private fun BackgroundSelector(selected: Background, onSelect: (Background) -> Unit) {
Section(label = "Background") {
ChipGrid(
items = Background.entries,
label = { it.label },
isSelected = { it == selected },
onSelect = onSelect,
)
}
}
@Composable
private fun PlaceholderSelector(selected: Placeholder, onSelect: (Placeholder) -> Unit) {
Section(label = "Placeholder") {
ChipGrid(
items = Placeholder.entries,
label = { it.label },
isSelected = { it == selected },
onSelect = onSelect,
)
}
}
@Composable
private fun Toggles(state: TangemSearchStory) {
Section(label = "Flags") {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
ToggleRow(
label = "close button (onCloseClick)",
checked = state.hasCloseButton,
onToggle = state.onCloseButtonToggle,
)
}
}
}
@Composable
private fun Section(label: String, content: @Composable () -> Unit) {
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
Text(
modifier = Modifier.padding(horizontal = 16.dp),
text = label,
style = TangemTheme.typography.subtitle1,
color = TangemTheme.colors.text.primary1,
)
content()
}
}
@Composable
private fun <T> ChipGrid(items: List<T>, label: (T) -> String, isSelected: (T) -> Boolean, onSelect: (T) -> Unit) {
val shape = RoundedCornerShape(50)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
.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),
) {
items.forEach { item ->
Chip(
label = label(item),
selected = isSelected(item),
onClick = { onSelect(item) },
modifier = Modifier.weight(1f),
)
}
}
}
@Composable
private fun Chip(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 ToggleRow(label: String, checked: Boolean, onToggle: () -> Unit) {
Row(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp))
.background(TangemTheme.colors2.surface.level2)
.clickable(onClick = onToggle)
.padding(horizontal = 12.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
) {
Text(
text = label,
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.primary1,
)
Text(
text = if (checked) "ON" else "OFF",
style = TangemTheme.typography.caption2,
color = if (checked) TangemTheme.colors.text.accent else TangemTheme.colors.text.secondary,
)
}
}

View file

@ -42,6 +42,7 @@ import com.tangem.feature.tester.presentation.storybook.page.ds.button.TangemBut
import com.tangem.feature.tester.presentation.storybook.page.ds.fade.TangemFadeStory
import com.tangem.feature.tester.presentation.storybook.page.ds.loader.TangemLoaderStory
import com.tangem.feature.tester.presentation.storybook.page.ds.row.TangemRowStory
import com.tangem.feature.tester.presentation.storybook.page.ds.search.TangemSearchStory
import com.tangem.feature.tester.presentation.storybook.page.ds.shimmer.TangemShimmerStory
import com.tangem.feature.tester.presentation.storybook.page.ds.topnavigation.TangemTopNavigationStory
import com.tangem.feature.tester.presentation.storybook.page.headerrow.TangemHeaderRowStory
@ -92,6 +93,7 @@ internal fun StoryBookScreen(state: StoryBookUM, modifier: Modifier = Modifier)
is TangemButtonStory -> TangemButtonStory(state = storyState)
is TangemBadgeV2Story -> TangemBadgeV2Story(state = storyState)
is TangemRowStory -> TangemRowStory(state = storyState)
is TangemSearchStory -> TangemSearchStory(state = storyState)
is TangemShimmerStory -> TangemShimmerStory(state = storyState)
is TangemFadeStory -> TangemFadeStory(state = storyState)
is TangemTopNavigationStory -> TangemTopNavigationStory(state = storyState)