Use separators to break content into visual groups without adding extra chrome.
import androidx.compose.runtime.Composable
import com.composables.ui.components.HorizontalSeparator
import com.composables.ui.components.VerticalSeparator
@Composable
fun HorizontalSeparatorExample() {
HorizontalSeparator()
}Installation
implementation("com.composables:ui:0.1.0")Add the required dependencies
implementation("com.composables:composeunstyled:2.7.0")
Copy and paste the following sources into your project
components/Separators.kt
package com.composables.ui.components
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.composables.ui.theme.borderColor
import com.composables.ui.theme.colors
import com.composeunstyled.UnstyledHorizontalSeparator
import com.composeunstyled.UnstyledVerticalSeparator
import com.composeunstyled.theme.Theme
/**
* A horizontal divider line.
* @param modifier Modifier applied to the separator.
* @param color Color used for the separator line.
* @param thickness Thickness of the separator line.
*/
@Composable
fun HorizontalSeparator(
modifier: Modifier = Modifier,
color: Color = Theme[colors][borderColor],
thickness: Dp = 1.dp,
) {
UnstyledHorizontalSeparator(
color = color,
modifier = modifier.clip(RoundedCornerShape(100)),
thickness = thickness,
)
}
/**
* A vertical divider line.
* @param modifier Modifier applied to the separator.
* @param color Color used for the separator line.
* @param thickness Thickness of the separator line.
*/
@Composable
fun VerticalSeparator(
modifier: Modifier = Modifier,
color: Color = Theme[colors][borderColor],
thickness: Dp = 1.dp,
) {
UnstyledVerticalSeparator(
color = color,
modifier = modifier.clip(RoundedCornerShape(100)),
thickness = thickness,
)
}components/Utils.kt
package com.composables.ui.components
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.interaction.InteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.composables.ui.theme.colors
import com.composables.ui.theme.ringColor
import com.composeunstyled.FocusRingVisibility
import com.composeunstyled.collectIsFocusVisibleAsState
import com.composeunstyled.outline
import com.composeunstyled.theme.Theme
@Composable
fun Modifier.focusRing(
interactionSource: InteractionSource,
width: Dp = 2.dp,
color: Color = Theme[colors][ringColor],
shape: Shape = RectangleShape,
offset: Dp = 0.dp,
visibility: FocusRingVisibility = FocusRingVisibility.FocusVisible,
): Modifier {
val showFocusRing by if (visibility == FocusRingVisibility.FocusVisible) {
interactionSource.collectIsFocusVisibleAsState()
} else {
interactionSource.collectIsFocusedAsState()
}
val animatedWidth by animateDpAsState(
targetValue = if (showFocusRing) width else 0.dp,
animationSpec = tween(durationMillis = 120),
label = "FocusRingWidth",
)
return this then Modifier.outline(
width = animatedWidth,
color = color,
shape = shape,
offset = offset,
)
}
@Composable
fun Modifier.bouncyPress(
interactionSource: InteractionSource,
enabled: Boolean = true,
pressedScale: Float = 0.98f,
): Modifier {
val pressed by interactionSource.collectIsPressedAsState()
val scale by animateFloatAsState(
targetValue = if (enabled && pressed) pressedScale else 1f,
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessMediumLow,
),
label = "BouncyPressScale",
)
return this then Modifier.graphicsLayer {
scaleX = scale
scaleY = scale
}
}Examples
Vertical
import androidx.compose.runtime.Composable
import com.composables.ui.components.VerticalSeparator
@Composable
fun VerticalSeparatorExample() {
VerticalSeparator()
}API Reference
HorizontalSeparator
A horizontal divider line.
@Composable
fun HorizontalSeparator(
modifier: Modifier = Modifier,
color: Color = Theme[colors][borderColor],
thickness: Dp = 1.dp,
)
| Parameter | Type | Description |
|---|---|---|
modifier |
Modifier |
Modifier applied to the separator. |
color |
Color |
Color used for the separator line. |
thickness |
Dp |
Thickness of the separator line. |
VerticalSeparator
A vertical divider line.
@Composable
fun VerticalSeparator(
modifier: Modifier = Modifier,
color: Color = Theme[colors][borderColor],
thickness: Dp = 1.dp,
)
| Parameter | Type | Description |
|---|---|---|
modifier |
Modifier |
Modifier applied to the separator. |
color |
Color |
Color used for the separator line. |
thickness |
Dp |
Thickness of the separator line. |