Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ import com.dbsystel.designsystem.foundation.theme.DesignSystemTheme
* @param icon wrapper class to define the icon to be displayed
* @param variant visual representation of the button
* @param size size of the button
* @param enabled controls the enabled state of this button. When false, this component will not respond to user input, and it will appear visually disabled and disabled to accessibility services.
* @param enabled controls the enabled state of this button. When false, this component will not
* respond to user input, and it will appear visually disabled and disabled to accessibility services.
* @param width width of the button
* @param onClick called when this button is clicked
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
package com.dbsystel.designsystem.components.link

import androidx.annotation.DrawableRes
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.dbsystel.designsystem.components.link.preview.previewName
import com.dbsystel.designsystem.foundation.R
import com.dbsystel.designsystem.foundation.theme.DesignSystemTheme

/**
* Links are used as navigation elements. They can stand alone, within a sentence or paragraph
* or directly after the content to which they refer.
*
* @param modifier the Modifier to be applied to this link
* @param text the text to be displayed
* @param content content type of the link (external or internal link)
* @param variant visual representation of the link
* @param size size of the link
* @param enabled controls the enabled state of this link. When false, this component will not
* respond to user input, and it will appear visually disabled and disabled to accessibility services.
* @param showIcon control the visibility of the content type icon
* @param onClick called when this link is clicked
*
* @sample com.dbsystel.designsystem.components.samples.DSLinkSample
*/
@Composable
fun DSLink(
modifier: Modifier = Modifier,
text: String,
content: DSLinkContent = DSLinkContent.INTERNAL,
variant: DSLinkVariant = DSLinkVariant.ADAPTIVE,
size: DSLinkSize = DSLinkSize.MEDIUM,
enabled: Boolean = true,
showIcon: Boolean = true,
onClick: () -> Unit,
) {
val interactionSource = remember { MutableInteractionSource() }
val pressed by interactionSource.collectIsPressedAsState()

val linkColor by animateColorAsState(
targetValue = if (pressed) variant.pressedColor else variant.color,
label = "LinkColorAnimation",
)

Row(
modifier = Modifier
.alpha(if (enabled) 1.0f else 0.4f)
.clickable(
enabled = enabled,
onClick = onClick,
interactionSource = interactionSource,
indication = null
)
.then(modifier),
horizontalArrangement = Arrangement.spacedBy(size.paddingH),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = text,
textDecoration = TextDecoration.Underline,
style = size.textStyle,
color = linkColor,
)
if (showIcon) Icon(
modifier = Modifier.size(size.iconSize),
painter = painterResource(content.iconRes),
contentDescription = content.name,
tint = linkColor,
)
}
}

enum class DSLinkVariant {
ADAPTIVE,
BRAND;

internal val color: Color
@Composable
@ReadOnlyComposable
get() = when (this) {
ADAPTIVE -> DesignSystemTheme.activeColor.Basic.Text.Emphasis100.Default
BRAND -> DesignSystemTheme.colors.brand.Basic.Text.Emphasis80.Default
}

internal val pressedColor: Color
@Composable
@ReadOnlyComposable
get() = when (this) {
ADAPTIVE -> DesignSystemTheme.activeColor.Basic.Text.Emphasis100.Pressed
BRAND -> DesignSystemTheme.colors.brand.Basic.Text.Emphasis80.Pressed
}
}

enum class DSLinkSize {
MEDIUM,
SMALL;

internal val paddingH: Dp
@Composable
@ReadOnlyComposable
get() = when (this) {
MEDIUM -> DesignSystemTheme.dimensions.spacing.fixed2xs
SMALL -> DesignSystemTheme.dimensions.spacing.fixed3xs
}

internal val iconSize: Dp
@Composable
@ReadOnlyComposable
get() = when (this) {
MEDIUM -> 24.dp
SMALL -> 20.dp
}

internal val textStyle: TextStyle
@Composable
@ReadOnlyComposable
get() = when (this) {
MEDIUM -> DesignSystemTheme.typography.bodyMd
SMALL -> DesignSystemTheme.typography.bodySm
}
}

enum class DSLinkContent {
INTERNAL,
EXTERNAL;

internal val iconRes: Int
@DrawableRes
get() = when (this) {
INTERNAL -> R.drawable.ds_ic_arrow_forward
EXTERNAL -> R.drawable.ds_ic_link_external
}
}

@Composable
@Preview(
showBackground = true,
group = "Content",
)
private fun DSLinkPreview_Content() {
DesignSystemTheme {
Row(
modifier = Modifier
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
DSLinkContent.entries.forEach { content ->
DSLink(
text = content.previewName,
content = content,
onClick = {},
)
}
}
}
}

@Composable
@Preview(
showBackground = true,
group = "Variant",
)
private fun DSLinkPreview_Variant() {
DesignSystemTheme {
Row(
modifier = Modifier
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
DSLinkVariant.entries.forEach { variant ->
DSLink(
text = variant.previewName,
variant = variant,
onClick = {},
)
}
}
}
}

@Composable
@Preview(
showBackground = true,
group = "Disabled",
)
private fun DSLinkPreview_Disabled() {
DesignSystemTheme {
Row(
modifier = Modifier
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
listOf(false, true).forEach { disabled ->
DSLink(
text = if (!disabled) "(Def) False" else "True",
enabled = !disabled,
onClick = {},
)
}
}
}
}

@Composable
@Preview(
showBackground = true,
group = "Size",
)
private fun DSLinkPreview_Size() {
DesignSystemTheme {
Row(
modifier = Modifier
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
DSLinkSize.entries.forEach { size ->
DSLink(
text = size.previewName,
size = size,
onClick = {},
)
}
}
}
}

@Composable
@Preview(
showBackground = true,
group = "ShowIcon",
)
private fun DSLinkPreview_ShowIcon() {
DesignSystemTheme {
Row(
modifier = Modifier
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
listOf(true, false).forEach { showIcon ->
DSLink(
text = if (showIcon) "(Def) True" else "False",
showIcon = showIcon,
onClick = {},
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.dbsystel.designsystem.components.link.preview

import com.dbsystel.designsystem.components.link.DSLinkContent
import com.dbsystel.designsystem.components.link.DSLinkSize
import com.dbsystel.designsystem.components.link.DSLinkVariant

internal val DSLinkContent.previewName: String
get() = when (this) {
DSLinkContent.INTERNAL -> "(Def) Internal"
DSLinkContent.EXTERNAL -> "External"
}

internal val DSLinkVariant.previewName: String
get() = when (this) {
DSLinkVariant.ADAPTIVE -> "(Def) Adaptive"
DSLinkVariant.BRAND -> "Brand"
}

internal val DSLinkSize.previewName: String
get() = when (this) {
DSLinkSize.MEDIUM -> "(Def) Medium"
DSLinkSize.SMALL -> "Small"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.dbsystel.designsystem.components.samples

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.dbsystel.designsystem.components.link.DSLink
import com.dbsystel.designsystem.components.link.DSLinkContent
import com.dbsystel.designsystem.components.link.DSLinkSize
import com.dbsystel.designsystem.components.link.DSLinkVariant

@Preview
@Composable
private fun DSLinkSample() {
DSLink(
text = "More",
variant = DSLinkVariant.BRAND,
size = DSLinkSize.MEDIUM,
content = DSLinkContent.INTERNAL,
enabled = true,
showIcon = true,
onClick = { /* Do something! */ },
)
}
2 changes: 1 addition & 1 deletion foundation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {

android {
namespace = "com.dbsystel.designsystem.foundation"
compileSdk = 34
compileSdk = 35

defaultConfig {
minSdk = 30
Expand Down
Empty file.
12 changes: 12 additions & 0 deletions foundation/src/main/res/drawable/ds_ic_arrow_forward.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M4,12C4,12.563 4.438,13 5,13L16.594,13L12.313,17.281C12.094,17.5 12,17.75 12,18C12,18.438 12.375,19 13.031,19C13.281,19 13.531,18.906 13.719,18.719L19.719,12.719C19.923,12.515 20,12.25 20,12C20.031,11.75 19.923,11.485 19.719,11.281L13.719,5.281C13.531,5.094 13.25,5 13.031,5C12.469,5 12,5.469 12,6C12,6.281 12.109,6.515 12.313,6.719L16.594,11L5,11C4.438,11 4,11.438 4,12Z"
android:strokeWidth="1"
android:fillColor="#282D37"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>
12 changes: 12 additions & 0 deletions foundation/src/main/res/drawable/ds_ic_link_external.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6.031,18C6.25,18 6.5,17.906 6.688,17.719L15,9.406L15,15C15,15.594 15.469,16.031 16,16.031C16.531,16.031 17,15.563 17,15L17,6.906C17,6.375 16.531,6 16,6L8,6C7.406,6 7,6.469 7,7C7,7.5 7.469,8 8,8L13.594,8L5.219,16.375C5.063,16.531 5,16.781 5,16.969C5,17.563 5.438,18 6.031,18Z"
android:strokeWidth="1"
android:fillColor="#282D37"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>
Loading