diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt index 56a96ba..acd2cbf 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt @@ -1,14 +1,17 @@ package com.team.prezel.core.designsystem.component.button +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.material3.Icon import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.LocalTextStyle -import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment @@ -17,8 +20,6 @@ import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.geometry.Offset import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.semantics.Role -import androidx.compose.ui.semantics.role -import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.icon.IconSource import com.team.prezel.core.designsystem.icon.PrezelIcons @@ -34,42 +35,59 @@ fun PrezelButton( enabled: Boolean = true, style: PrezelButtonStyle = PrezelButtonStyle(), ) { - val hasText = text != null - val hasIcon = icon != null - require(hasText || hasIcon) { "Button은 text 또는 icon 중 하나는 반드시 필요합니다." } - val (buttonType, buttonHierarchy, buttonSize, isRounded) = style - val isIconOnly = !hasText + require(text != null || icon != null) { "버튼은 텍스트 또는 아이콘 중 하나는 반드시 필요합니다." } + val appearance = PrezelButtonAppearance.of(style = style, isIconOnly = text == null, enabled = enabled) - Surface( - onClick = onClick, - modifier = modifier.semantics { role = Role.Button }, - enabled = enabled, - shape = prezelButtonShape(isIconOnly = isIconOnly, isRounded = isRounded, buttonSize = buttonSize), - color = prezelButtonContainerColor(type = buttonType, hierarchy = buttonHierarchy, enabled = enabled), - border = prezelButtonBorderStroke(type = buttonType, hierarchy = buttonHierarchy, enabled = enabled), + Box( + modifier = modifier + .applyButtonAppearance(appearance) + .clickable( + enabled = enabled, + onClick = onClick, + role = Role.Button, + indication = ripple(), + interactionSource = null, + ), + contentAlignment = Alignment.Center, ) { - CompositionLocalProvider( - LocalTextStyle provides prezelButtonTextStyle(buttonSize), - LocalContentColor provides prezelButtonContentColor(type = buttonType, hierarchy = buttonHierarchy, enabled = enabled), + PrezelButtonContent( + text = text, + icon = icon, + showUnderline = style.showUnderline, + appearance = appearance, + ) + } +} + +@Composable +private fun PrezelButtonContent( + text: String?, + icon: IconSource?, + showUnderline: Boolean, + appearance: PrezelButtonAppearance, +) { + CompositionLocalProvider(LocalContentColor provides appearance.contentColor) { + Row( + modifier = Modifier.padding(appearance.contentPadding), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, ) { - Row( - modifier = Modifier.padding(prezelButtonContentPadding(size = buttonSize, isOnlyIcon = isIconOnly)), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, - ) { - icon?.let { source -> - PrezelButtonIcon(icon = source, size = buttonSize) - } + icon?.let { source -> + Icon( + painter = source.painter(), + contentDescription = source.contentDescription(), + modifier = Modifier.size(appearance.iconSize), + ) + } - if (!hasText) return@Row - if (hasIcon) { - val spacing = if (buttonSize == PrezelButtonSize.REGULAR) PrezelTheme.spacing.V8 else PrezelTheme.spacing.V4 - Spacer(modifier = Modifier.width(width = spacing)) + text?.let { label -> + if (icon != null) { + Spacer(modifier = Modifier.width(width = appearance.iconSpacing)) } - Text( - text = text, - modifier = Modifier.applyButtonTextStyle(style), + text = label, + style = appearance.textStyle, + modifier = if (showUnderline) Modifier.prezelButtonUnderline() else Modifier, ) } } @@ -77,19 +95,17 @@ fun PrezelButton( } @Composable -private fun Modifier.applyButtonTextStyle(style: PrezelButtonStyle): Modifier { - if (!style.showUnderline) return this - - val px = with(LocalDensity.current) { 1.dp.toPx() } +private fun Modifier.prezelButtonUnderline(): Modifier { + val underlineThickness = with(LocalDensity.current) { 1.dp.toPx() } val underlineColor = PrezelTheme.colors.borderLarge return this.drawBehind { - val y = size.height - (px / 2) + val y = size.height - (underlineThickness / 2) drawLine( color = underlineColor, start = Offset(0f, y), end = Offset(size.width, y), - strokeWidth = px, + strokeWidth = underlineThickness, ) } } @@ -122,6 +138,7 @@ private fun PrezelButtonPreviewGhost() { private fun PrezelButtonPreviewItem( style: PrezelButtonStyle, enabled: Boolean, + modifier: Modifier = Modifier, ) { PrezelButton( text = "Label", @@ -129,5 +146,6 @@ private fun PrezelButtonPreviewItem( onClick = {}, enabled = enabled, style = style, + modifier = modifier, ) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt index 0694e42..70d4fa7 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt @@ -7,13 +7,15 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.PreviewScaffold import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.util.drawDashBorder import kotlinx.collections.immutable.persistentListOf -internal typealias PrezelButtonPreviewContent = @Composable (PrezelButtonStyle, Boolean) -> Unit +internal typealias PrezelButtonPreviewContent = @Composable (style: PrezelButtonStyle, enabled: Boolean, contentModifier: Modifier) -> Unit @Immutable private data class PreviewVariant( @@ -28,16 +30,11 @@ private val PreviewVariants = persistentListOf( PreviewVariant(enabled = false, isRounded = false), ) -private val PreviewSizes = persistentListOf( - PrezelButtonSize.XSMALL, - PrezelButtonSize.SMALL, - PrezelButtonSize.REGULAR, -) - @Composable internal fun PrezelButtonPreviewByType( type: PrezelButtonType, content: PrezelButtonPreviewContent, + isIconOnly: Boolean = false, ) { PreviewScaffold { Text(text = type.name, style = PrezelTheme.typography.title2Medium) @@ -48,6 +45,7 @@ internal fun PrezelButtonPreviewByType( type = type, enabled = variant.enabled, isRounded = variant.isRounded, + isIconOnly = isIconOnly, content = content, ) } @@ -59,8 +57,10 @@ private fun PrezelButtonVariantSection( type: PrezelButtonType, enabled: Boolean, isRounded: Boolean, + isIconOnly: Boolean, content: PrezelButtonPreviewContent, modifier: Modifier = Modifier, + contentModifier: Modifier = Modifier, ) { Column( modifier = modifier, @@ -72,7 +72,9 @@ private fun PrezelButtonVariantSection( hierarchy = PrezelButtonHierarchy.PRIMARY, enabled = enabled, isRounded = isRounded, + isIconOnly = isIconOnly, content = content, + contentModifier = contentModifier, ) Text(text = "Hierarchy: Secondary | Enabled: $enabled | Radius: $isRounded", style = PrezelTheme.typography.body3Medium) PrezelButtonPreviewHierarchyBlock( @@ -80,7 +82,9 @@ private fun PrezelButtonVariantSection( hierarchy = PrezelButtonHierarchy.SECONDARY, enabled = enabled, isRounded = isRounded, + isIconOnly = isIconOnly, content = content, + contentModifier = contentModifier, ) } } @@ -91,22 +95,32 @@ private fun PrezelButtonPreviewHierarchyBlock( hierarchy: PrezelButtonHierarchy, enabled: Boolean, isRounded: Boolean, + isIconOnly: Boolean, content: PrezelButtonPreviewContent, modifier: Modifier = Modifier, + contentModifier: Modifier = Modifier, ) { Row( modifier = modifier, horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, ) { - PreviewSizes.forEach { size -> + PrezelButtonSize.entries.forEach { size -> + val style = PrezelButtonStyle( + buttonType = type, + buttonHierarchy = hierarchy, + buttonSize = size, + isRounded = isRounded, + ) + val appearance = PrezelButtonAppearance.of(style = style, isIconOnly = isIconOnly, enabled = enabled) + content( - PrezelButtonStyle( - buttonType = type, - buttonHierarchy = hierarchy, - buttonSize = size, - isRounded = isRounded, - ), + style, enabled, + contentModifier + .then( + if (type == PrezelButtonType.GHOST) Modifier.drawDashBorder(shape = appearance.shape) else Modifier, + ), ) } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt index 50bdf88..2f5d73a 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt @@ -1,22 +1,22 @@ package com.team.prezel.core.designsystem.component.button import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.size -import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.foundation.color.PrezelColors import com.team.prezel.core.designsystem.foundation.number.PrezelShapes import com.team.prezel.core.designsystem.foundation.number.PrezelSpacing import com.team.prezel.core.designsystem.foundation.number.PrezelStroke -import com.team.prezel.core.designsystem.icon.IconSource import com.team.prezel.core.designsystem.theme.PrezelColorScheme import com.team.prezel.core.designsystem.theme.PrezelTheme @@ -46,27 +46,78 @@ data class PrezelButtonStyle( val showUnderline: Boolean = false, ) -@Composable -internal fun PrezelButtonIcon( - icon: IconSource, - size: PrezelButtonSize, - modifier: Modifier = Modifier, +@Immutable +internal data class PrezelButtonAppearance( + val textStyle: TextStyle, + val contentColor: Color, + val contentPadding: PaddingValues, + val iconSpacing: Dp, + val shape: Shape, + val containerColor: Color, + val borderStroke: BorderStroke, + val iconSize: Dp, ) { - Icon( - painter = icon.painter(), - contentDescription = icon.contentDescription(), - modifier = modifier.size( - when (size) { - PrezelButtonSize.XSMALL -> 14.dp - PrezelButtonSize.SMALL -> 16.dp - PrezelButtonSize.REGULAR -> 20.dp - }, - ), - ) + companion object { + @Composable + fun of( + style: PrezelButtonStyle, + isIconOnly: Boolean, + enabled: Boolean, + ): PrezelButtonAppearance = + PrezelButtonAppearance( + textStyle = prezelButtonTextStyle(size = style.buttonSize), + contentColor = prezelButtonContentColor( + type = style.buttonType, + hierarchy = style.buttonHierarchy, + enabled = enabled, + ), + contentPadding = prezelButtonContentPadding( + size = style.buttonSize, + isIconOnly = isIconOnly, + ), + iconSpacing = prezelButtonIconSpacing(size = style.buttonSize), + shape = prezelButtonShape( + isIconOnly = isIconOnly, + isRounded = style.isRounded, + buttonSize = style.buttonSize, + ), + containerColor = prezelButtonContainerColor( + type = style.buttonType, + hierarchy = style.buttonHierarchy, + enabled = enabled, + ), + borderStroke = prezelButtonBorderStroke( + type = style.buttonType, + hierarchy = style.buttonHierarchy, + enabled = enabled, + ), + iconSize = prezelButtonIconSize(size = style.buttonSize), + ) + } } +internal fun Modifier.applyButtonAppearance(appearance: PrezelButtonAppearance): Modifier = + this + .clip(appearance.shape) + .background(appearance.containerColor) + .border( + border = appearance.borderStroke, + shape = appearance.shape, + ) + @Composable -internal fun prezelButtonShape( +private fun prezelButtonIconSpacing( + size: PrezelButtonSize, + spacing: PrezelSpacing = PrezelTheme.spacing, +): Dp = + when (size) { + PrezelButtonSize.XSMALL -> spacing.V4 + PrezelButtonSize.SMALL -> spacing.V4 + PrezelButtonSize.REGULAR -> spacing.V8 + } + +@Composable +private fun prezelButtonShape( isIconOnly: Boolean, isRounded: Boolean, buttonSize: PrezelButtonSize, @@ -84,7 +135,7 @@ internal fun prezelButtonShape( } @Composable -internal fun prezelButtonBorderStroke( +private fun prezelButtonBorderStroke( type: PrezelButtonType, hierarchy: PrezelButtonHierarchy, enabled: Boolean, @@ -103,7 +154,7 @@ internal fun prezelButtonBorderStroke( } @Composable -internal fun prezelButtonTextStyle(size: PrezelButtonSize): TextStyle = +private fun prezelButtonTextStyle(size: PrezelButtonSize): TextStyle = when (size) { PrezelButtonSize.XSMALL -> PrezelTheme.typography.caption2Medium PrezelButtonSize.SMALL -> PrezelTheme.typography.body3Medium @@ -111,7 +162,7 @@ internal fun prezelButtonTextStyle(size: PrezelButtonSize): TextStyle = } @Composable -internal fun prezelButtonContainerColor( +private fun prezelButtonContainerColor( type: PrezelButtonType, hierarchy: PrezelButtonHierarchy, enabled: Boolean, @@ -131,7 +182,7 @@ internal fun prezelButtonContainerColor( } @Composable -internal fun prezelButtonContentColor( +private fun prezelButtonContentColor( type: PrezelButtonType, hierarchy: PrezelButtonHierarchy, enabled: Boolean, @@ -141,19 +192,19 @@ internal fun prezelButtonContentColor( if (hierarchy == PrezelButtonHierarchy.SECONDARY) return colors.textMedium return when (type) { - PrezelButtonType.FILLED -> if (isSystemInDarkTheme()) colors.textLarge else PrezelColorScheme.Dark.textLarge + PrezelButtonType.FILLED -> PrezelColorScheme.Dark.textLarge PrezelButtonType.OUTLINED -> colors.interactiveRegular PrezelButtonType.GHOST -> colors.interactiveRegular } } @Composable -internal fun prezelButtonContentPadding( +private fun prezelButtonContentPadding( size: PrezelButtonSize, - isOnlyIcon: Boolean, + isIconOnly: Boolean, spacing: PrezelSpacing = PrezelTheme.spacing, ): PaddingValues { - if (isOnlyIcon) return prezelIconButtonContentPadding(size) + if (isIconOnly) return prezelIconButtonContentPadding(size) val horizontal = when (size) { PrezelButtonSize.XSMALL -> spacing.V10 @@ -182,3 +233,11 @@ private fun prezelIconButtonContentPadding( PrezelButtonSize.REGULAR -> spacing.V14 }, ) + +@Composable +private fun prezelButtonIconSize(size: PrezelButtonSize): Dp = + when (size) { + PrezelButtonSize.XSMALL -> 14.dp + PrezelButtonSize.SMALL -> 16.dp + PrezelButtonSize.REGULAR -> 20.dp + } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelIconButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelIconButton.kt index 0401b74..8fc52ff 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelIconButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelIconButton.kt @@ -28,7 +28,7 @@ fun PrezelIconButton( @Composable private fun PrezelIconButtonPreviewFilled() { PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.FILLED, content = ::PrezelIconButtonPreviewItem) + PrezelButtonPreviewByType(type = PrezelButtonType.FILLED, content = ::PrezelIconButtonPreviewItem, isIconOnly = true) } } @@ -36,7 +36,7 @@ private fun PrezelIconButtonPreviewFilled() { @Composable private fun PrezelIconButtonPreviewOutlined() { PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.OUTLINED, content = ::PrezelIconButtonPreviewItem) + PrezelButtonPreviewByType(type = PrezelButtonType.OUTLINED, content = ::PrezelIconButtonPreviewItem, isIconOnly = true) } } @@ -44,7 +44,7 @@ private fun PrezelIconButtonPreviewOutlined() { @Composable private fun PrezelIconButtonPreviewGhost() { PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.GHOST, content = ::PrezelIconButtonPreviewItem) + PrezelButtonPreviewByType(type = PrezelButtonType.GHOST, content = ::PrezelIconButtonPreviewItem, isIconOnly = true) } } @@ -52,11 +52,13 @@ private fun PrezelIconButtonPreviewGhost() { private fun PrezelIconButtonPreviewItem( style: PrezelButtonStyle, enabled: Boolean, + modifier: Modifier = Modifier, ) { PrezelIconButton( icon = IconSource(resId = PrezelIcons.Blank), onClick = {}, enabled = enabled, style = style, + modifier = modifier, ) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelTextButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelTextButton.kt index 3973f49..0c60503 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelTextButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelTextButton.kt @@ -50,11 +50,13 @@ private fun PrezelTextButtonPreviewGhost() { private fun PrezelTextButtonPreviewItem( style: PrezelButtonStyle, enabled: Boolean, + modifier: Modifier = Modifier, ) { PrezelTextButton( text = "Label", onClick = {}, enabled = enabled, style = style, + modifier = modifier, ) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt new file mode 100644 index 0000000..2c794cb --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt @@ -0,0 +1,85 @@ +package com.team.prezel.core.designsystem.util + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawWithCache +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Outline +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.PathEffect +import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +/** + * 점선 테두리를 그리는 [Modifier] 확장 함수. + * + * [shape] 형태의 외곽선을 기준으로 점선(border)을 렌더링한다. + * + * @param color 테두리 색상 + * @param shape 테두리 모양 + * @param width 테두리 두께(px) + * @param interval 대시와 간격의 길이(px) + * @param phase 대시 패턴 시작 오프셋(px) + */ +fun Modifier.drawDashBorder( + color: Color = Color.Gray, + shape: Shape = RectangleShape, + width: Float = 1f, + interval: Float = 10f, + phase: Float = 0f, +) = this.drawWithCache { + val outline = shape.createOutline(size, layoutDirection, this) + val pathEffect = PathEffect.dashPathEffect(floatArrayOf(interval, interval), phase) + val stroke = Stroke(width = width, pathEffect = pathEffect) + + onDrawBehind { + when (outline) { + is Outline.Rectangle -> { + drawRect( + color = color, + topLeft = outline.rect.topLeft, + size = outline.rect.size, + style = stroke, + ) + } + + is Outline.Rounded -> { + drawPath( + path = Path().apply { addRoundRect(outline.roundRect) }, + color = color, + style = stroke, + ) + } + + is Outline.Generic -> { + drawPath( + path = outline.path, + color = color, + style = stroke, + ) + } + } + } +} + +@ThemePreview +@Composable +private fun DrawDashBorderPreview() { + PrezelTheme { + Box( + modifier = Modifier + .fillMaxWidth() + .height(100.dp) + .padding(12.dp) + .drawDashBorder(), + ) + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrowDashBorder.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrowDashBorder.kt deleted file mode 100644 index 8d09b33..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrowDashBorder.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.team.prezel.core.designsystem.util - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.PathEffect -import androidx.compose.ui.graphics.drawscope.Stroke -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.theme.PrezelTheme - -fun Modifier.drawDashBorder( - color: Color = Color.Gray, - width: Float = 1f, - interval: Float = 10f, - phase: Float = 0f, -) = this.drawBehind { - drawRoundRect( - color = color, - style = Stroke( - width = width, - pathEffect = PathEffect.dashPathEffect(floatArrayOf(interval, interval), phase), - ), - ) -} - -@ThemePreview -@Composable -private fun DrawDashBorderPreview() { - PrezelTheme { - Box( - modifier = Modifier - .fillMaxWidth() - .height(100.dp) - .padding(12.dp) - .drawDashBorder(), - ) - } -}