Skip to content
Draft
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 @@ -151,7 +151,7 @@ class ColorPaletteFragment : Fragment() {
DaxColorAttributeListItem(
text = "Primary Text",
dotColors = DaxColorDotColors(
fillColor = DuckDuckGoTheme.textColors.primary,
fillColor = DuckDuckGoTheme.colors.text.primary,
strokeColor = DuckDuckGoTheme.colors.backgrounds.backgroundInverted,
),
)
Expand All @@ -162,7 +162,7 @@ class ColorPaletteFragment : Fragment() {
DaxColorAttributeListItem(
text = "Secondary Text",
dotColors = DaxColorDotColors(
fillColor = DuckDuckGoTheme.textColors.secondary,
fillColor = DuckDuckGoTheme.colors.text.secondary,
strokeColor = DuckDuckGoTheme.colors.backgrounds.backgroundInverted,
),
)
Expand All @@ -173,7 +173,7 @@ class ColorPaletteFragment : Fragment() {
DaxColorAttributeListItem(
text = "Text Disabled",
dotColors = DaxColorDotColors(
fillColor = DuckDuckGoTheme.textColors.disabled,
fillColor = DuckDuckGoTheme.colors.text.disabled,
strokeColor = DuckDuckGoTheme.colors.backgrounds.backgroundInverted,
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,26 @@

package com.duckduckgo.common.ui.compose.text

import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.takeOrElse
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewLightDark
import com.duckduckgo.common.ui.compose.theme.DuckDuckGoTextStyle
import com.duckduckgo.common.ui.compose.theme.DuckDuckGoTheme
import com.duckduckgo.common.ui.compose.theme.asTextStyle
import com.duckduckgo.common.ui.compose.tools.PreviewBox
import com.duckduckgo.common.ui.compose.tools.PreviewBoxInverted

/**
* Base text component for the DuckDuckGo design system.
*
* @param color The text color. Should use colors from [DuckDuckGoTheme.textColors] for consistency
* with the design system (e.g., [DuckDuckGoTheme.textColors.primary], [DuckDuckGoTheme.textColors.secondary]).
* @param color The text color. Should use colors from [DuckDuckGoTheme.colors.text] for consistency
* with the design system (e.g., [DuckDuckGoTheme.colors.text.primary], [DuckDuckGoTheme.colors.text.secondary]).
* A lint rule will warn if arbitrary colors are used.
*
* Asana Task: https://app.asana.com/1/137249556945/project/1202857801505092/task/1211634956773768
Expand All @@ -43,16 +45,17 @@ import com.duckduckgo.common.ui.compose.tools.PreviewBoxInverted
fun DaxText(
text: String,
modifier: Modifier = Modifier,
style: DuckDuckGoTextStyle = DuckDuckGoTheme.typography.body1,
color: Color = DuckDuckGoTheme.textColors.primary,
color: Color = Color.Unspecified,
style: TextStyle = LocalTextStyle.current,
textAlign: TextAlign? = null,
overflow: TextOverflow = TextOverflow.Ellipsis,
maxLines: Int = Int.MAX_VALUE,
) {
val textColor = color.takeOrElse { style.color.takeOrElse { LocalContentColor.current } }
Text(
text = text,
color = color,
style = style.asTextStyle,
color = textColor,
style = style,
textAlign = textAlign,
overflow = overflow,
maxLines = maxLines,
Expand Down Expand Up @@ -170,7 +173,7 @@ private fun DaxTextColorPrimaryPreview() {
PreviewBox {
DaxText(
text = "Primary Color",
color = DuckDuckGoTheme.textColors.primary,
color = DuckDuckGoTheme.colors.text.primary,
)
}
}
Expand All @@ -181,7 +184,7 @@ private fun DaxTextColorPrimaryInvertedPreview() {
PreviewBoxInverted {
DaxText(
text = "Primary Inverted",
color = DuckDuckGoTheme.textColors.primaryInverted,
color = DuckDuckGoTheme.colors.text.primaryInverted,
)
}
}
Expand All @@ -192,7 +195,7 @@ private fun DaxTextColorSecondaryPreview() {
PreviewBox {
DaxText(
text = "Secondary Color",
color = DuckDuckGoTheme.textColors.secondary,
color = DuckDuckGoTheme.colors.text.secondary,
)
}
}
Expand All @@ -203,7 +206,7 @@ private fun DaxTextColorSecondaryInvertedPreview() {
PreviewBoxInverted {
DaxText(
text = "Secondary Inverted",
color = DuckDuckGoTheme.textColors.secondaryInverted,
color = DuckDuckGoTheme.colors.text.secondaryInverted,
)
}
}
Expand All @@ -214,7 +217,7 @@ private fun DaxTextColorTertiaryPreview() {
PreviewBox {
DaxText(
text = "Tertiary Color",
color = DuckDuckGoTheme.textColors.tertiary,
color = DuckDuckGoTheme.colors.text.tertiary,
)
}
}
Expand All @@ -225,7 +228,7 @@ private fun DaxTextColorDisabledPreview() {
PreviewBox {
DaxText(
text = "Disabled Color",
color = DuckDuckGoTheme.textColors.disabled,
color = DuckDuckGoTheme.colors.text.disabled,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ package com.duckduckgo.common.ui.compose.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.shape.CutCornerShape
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProvideTextStyle
import androidx.compose.material3.Shapes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
Expand All @@ -36,11 +38,6 @@ object DuckDuckGoTheme {
@ReadOnlyComposable
get() = LocalDuckDuckGoColors.current

val textColors: DuckDuckGoTextColors
@Composable
@ReadOnlyComposable
get() = colors.text

val shapes
@Composable
@ReadOnlyComposable
Expand Down Expand Up @@ -177,7 +174,17 @@ fun DuckDuckGoTheme(
colorScheme = debugColors(),
typography = debugTypography(),
shapes = debugShapes,
content = content,
content = {
ProvideTextStyle(
LocalDuckDuckGoTypography.current.body1,
content = {
CompositionLocalProvider(
LocalContentColor provides colors.text.primary,
content = content,
)
},
)
},
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,110 +39,78 @@ private val RobotoMono = FontFamily(
@Immutable
data class DuckDuckGoTypography(

val title: DuckDuckGoTextStyle =
DuckDuckGoTextStyle(
TextStyle(
fontSize = 32.sp,
lineHeight = 36.sp,
fontWeight = FontWeight.Bold,
),
),

val h1: DuckDuckGoTextStyle =
DuckDuckGoTextStyle(
TextStyle(
fontSize = 24.sp,
lineHeight = 30.sp,
fontWeight = FontWeight.Bold,
),
),

val h2: DuckDuckGoTextStyle =
DuckDuckGoTextStyle(
TextStyle(
fontSize = 20.sp,
lineHeight = 24.sp,
letterSpacing = 0.3.sp,
fontWeight = FontWeight.Medium,
),
),

val h3: DuckDuckGoTextStyle =
DuckDuckGoTextStyle(
TextStyle(
fontSize = 16.sp,
lineHeight = 21.sp,
fontWeight = FontWeight.Medium,
),
),

val h4: DuckDuckGoTextStyle =
DuckDuckGoTextStyle(
TextStyle(
fontSize = 14.sp,
lineHeight = 20.sp,
letterSpacing = 0.3.sp,
fontWeight = FontWeight.Medium,
),
),

val h5: DuckDuckGoTextStyle =
DuckDuckGoTextStyle(
TextStyle(
fontSize = 13.sp,
lineHeight = 16.sp,
fontWeight = FontWeight.Medium,
),
),

val body1: DuckDuckGoTextStyle = DuckDuckGoTextStyle(
TextStyle(
fontSize = 16.sp,
lineHeight = 20.sp,
),
val title: TextStyle = TextStyle(
fontSize = 32.sp,
lineHeight = 36.sp,
fontWeight = FontWeight.Bold,
),

val body1Bold: DuckDuckGoTextStyle = DuckDuckGoTextStyle(
body1.textStyle.copy(
fontWeight = FontWeight.Bold,
),
val h1: TextStyle = TextStyle(
fontSize = 24.sp,
lineHeight = 30.sp,
fontWeight = FontWeight.Bold,
),

val body1Mono: DuckDuckGoTextStyle = DuckDuckGoTextStyle(
body1.textStyle.copy(
fontFamily = RobotoMono,
),
val h2: TextStyle = TextStyle(
fontSize = 20.sp,
lineHeight = 24.sp,
letterSpacing = 0.3.sp,
fontWeight = FontWeight.Medium,
),

val body2: DuckDuckGoTextStyle = DuckDuckGoTextStyle(
TextStyle(
fontSize = 14.sp,
lineHeight = 18.sp,
letterSpacing = 0.2.sp,
),
val h3: TextStyle = TextStyle(
fontSize = 16.sp,
lineHeight = 21.sp,
fontWeight = FontWeight.Medium,
),

val body2Bold: DuckDuckGoTextStyle = DuckDuckGoTextStyle(
body2.textStyle.copy(
fontWeight = FontWeight.Bold,
letterSpacing = 0.3.sp,
),
val h4: TextStyle = TextStyle(
fontSize = 14.sp,
lineHeight = 20.sp,
letterSpacing = 0.3.sp,
fontWeight = FontWeight.Medium,
),

val button: DuckDuckGoTextStyle = DuckDuckGoTextStyle(
TextStyle(
fontSize = 15.sp,
lineHeight = 20.sp,
fontWeight = FontWeight.Bold,
),
val h5: TextStyle = TextStyle(
fontSize = 13.sp,
lineHeight = 16.sp,
fontWeight = FontWeight.Medium,
),

val caption: DuckDuckGoTextStyle = DuckDuckGoTextStyle(
TextStyle(
fontSize = 12.sp,
lineHeight = 16.sp,
letterSpacing = 0.2.sp,
),
val body1: TextStyle = TextStyle(
fontSize = 16.sp,
lineHeight = 20.sp,
),

val body1Bold: TextStyle = body1.copy(
fontWeight = FontWeight.Bold,
),

val body1Mono: TextStyle = body1.copy(
fontFamily = RobotoMono,
),

val body2: TextStyle = TextStyle(
fontSize = 14.sp,
lineHeight = 18.sp,
letterSpacing = 0.2.sp,
),

val body2Bold: TextStyle = body2.copy(
fontWeight = FontWeight.Bold,
letterSpacing = 0.3.sp,
),

val button: TextStyle = TextStyle(
fontSize = 15.sp,
lineHeight = 20.sp,
fontWeight = FontWeight.Bold,
),

val caption: TextStyle = TextStyle(
fontSize = 12.sp,
lineHeight = 16.sp,
letterSpacing = 0.2.sp,
),
)

Expand All @@ -152,13 +120,3 @@ val Typography = DuckDuckGoTypography()
val LocalDuckDuckGoTypography = staticCompositionLocalOf<DuckDuckGoTypography> {
error("No DuckDuckGoTypography provided")
}

@JvmInline
@Immutable
value class DuckDuckGoTextStyle internal constructor(
internal val textStyle: TextStyle,
)

// Internal extension to extract TextStyle - only accessible within the design system
internal val DuckDuckGoTextStyle.asTextStyle: TextStyle
get() = textStyle
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ class DaxTextColorUsageDetector : Detector(), SourceCodeScanner {
private fun isFromDuckDuckGoTextColors(argument: org.jetbrains.uast.UExpression): Boolean {
val source = argument.sourcePsi?.text ?: return false

// Check if the source contains DuckDuckGoTheme.textColors or theme.textColors
// Check if the source contains DuckDuckGoTheme.colors.text or theme.colors.text
// This covers cases like:
// - DuckDuckGoTheme.textColors.primary
// - theme.textColors.secondary
return source.contains("DuckDuckGoTheme.textColors") ||
source.contains("theme.textColors") ||
source.contains(".textColors.")
// - DuckDuckGoTheme.colors.text.primary
// - theme.colors.text.secondary
return source.contains("DuckDuckGoTheme.colors.text") ||
source.contains("theme.colors.text") ||
source.contains(".colors.text")
}

private fun reportInvalidColorUsage(colorArgument: org.jetbrains.uast.UExpression) {
Expand All @@ -88,11 +88,11 @@ class DaxTextColorUsageDetector : Detector(), SourceCodeScanner {
id = "InvalidDaxTextColorUsage",
briefDescription = "DaxText color parameter should use DuckDuckGoTheme.textColors",
explanation = """
Use DuckDuckGoTheme.textColors instead of arbitrary Color values to maintain design system consistency and theme support.
Use DuckDuckGoTheme.colors.text instead of arbitrary Color values to maintain design system consistency and theme support.

Examples:
• DuckDuckGoTheme.textColors.primary
• DuckDuckGoTheme.textColors.secondary
• DuckDuckGoTheme.colors.text.primary
• DuckDuckGoTheme.colors.text.secondary

For one-off cases requiring custom colors, use good judgement or consider raising it in the Android Design System AOR.
""".trimIndent(),
Expand Down
Loading
Loading