Skip to content

Commit

Permalink
Chore: Enable explicit API on material-color-utilities (#96)
Browse files Browse the repository at this point in the history
* enable explicit api
  • Loading branch information
jordond authored Feb 2, 2024
1 parent ce38e2a commit fc9c52e
Show file tree
Hide file tree
Showing 42 changed files with 1,121 additions and 303 deletions.
1 change: 0 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ plugins {
apiValidation {
ignoredProjects.addAll(
listOf(
"material-color-utilities",
"composeApp",
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import com.materialkolor.PaletteStyle
import com.materialkolor.demo.theme.AppTheme
import com.materialkolor.ktx.fromColor
import com.materialkolor.ktx.harmonize
import com.materialkolor.ktx.matchSaturation
import com.materialkolor.palettes.TonalPalette

val SampleColors = listOf(
Expand Down Expand Up @@ -109,7 +108,12 @@ internal fun App() {
var darkTheme by remember { mutableStateOf(isDarkTheme) }

AppTheme(seedColor, style, darkTheme) {
Column(modifier = Modifier.fillMaxSize().padding(8.dp)) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(8.dp)
.verticalScroll(rememberScrollState()),
) {
Box(
modifier = Modifier.align(Alignment.End)
) {
Expand Down Expand Up @@ -160,7 +164,7 @@ internal fun App() {

Text(text = "Preview", style = MaterialTheme.typography.headlineSmall)
Column(
modifier = Modifier.verticalScroll(rememberScrollState()),
modifier = Modifier,
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
Column {
Expand Down Expand Up @@ -207,7 +211,6 @@ internal fun App() {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.weight(1f),
) {
ExtendedFloatingActionButton({}) {
Text("Extended FAB")
Expand Down Expand Up @@ -261,8 +264,7 @@ internal fun App() {

Row {
val harmonizedColor = Color.Red
.matchSaturation(colorScheme.primary)
.harmonize(colorScheme.primary)
.harmonize(colorScheme.primary, matchSaturation = true)

val harmonizedPalette = TonalPalette.fromColor(harmonizedColor)

Expand Down Expand Up @@ -298,8 +300,7 @@ internal fun App() {

Row {
val harmonizedColor = Color.Blue
.matchSaturation(colorScheme.primary)
.harmonize(colorScheme.primary)
.harmonize(colorScheme.primary, matchSaturation = true)

val harmonizedPalette = TonalPalette.fromColor(harmonizedColor)

Expand Down
327 changes: 327 additions & 0 deletions material-color-utilities/api/android/material-color-utilities.api

Large diffs are not rendered by default.

327 changes: 327 additions & 0 deletions material-color-utilities/api/jvm/material-color-utilities.api

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions material-color-utilities/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ plugins {
}

kotlin {
explicitApi()

applyDefaultHierarchyTemplate()

androidTarget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ import com.materialkolor.utils.MathUtils.rotationDirection
import com.materialkolor.utils.MathUtils.sanitizeDegrees
import kotlin.math.min

/** Functions for blending in HCT and CAM16. */
/**
* Functions for blending in HCT and CAM16.
*/
@Suppress("MemberVisibilityCanBePrivate")
public object Blend {

/**
Expand All @@ -36,7 +39,7 @@ public object Blend {
* @return The design color with a hue shifted towards the system's color, a slightly
* warmer/cooler variant of the design color's hue.
*/
fun harmonize(designColor: Int, sourceColor: Int): Int {
public fun harmonize(designColor: Int, sourceColor: Int): Int {
val fromHct = Hct.fromInt(designColor)
val toHct = Hct.fromInt(sourceColor)
return harmonize(fromHct, toHct).toInt()
Expand All @@ -51,7 +54,7 @@ public object Blend {
* @return The design color with a hue shifted towards the system's color, a slightly
* warmer/cooler variant of the design color's hue.
*/
fun harmonize(designColor: Hct, sourceColor: Hct): Hct {
public fun harmonize(designColor: Hct, sourceColor: Hct): Hct {
val differenceDegrees = differenceDegrees(designColor.hue, sourceColor.hue)
val rotationDegrees: Double = min(differenceDegrees * 0.5, 15.0)
val rotationDirection = rotationDirection(designColor.hue, sourceColor.hue)
Expand All @@ -68,7 +71,7 @@ public object Blend {
* @param amount how much blending to perform; 0.0 >= and <= 1.0
* @return from, with a hue blended towards to. Chroma and tone are constant.
*/
fun hctHue(from: Int, to: Int, amount: Double): Int {
public fun hctHue(from: Int, to: Int, amount: Double): Int {
val ucs = cam16Ucs(from, to, amount)
val ucsCam = Cam16.fromInt(ucs)
val fromCam = Cam16.fromInt(from)
Expand All @@ -84,7 +87,7 @@ public object Blend {
* @param amount how much blending to perform; 0.0 >= and <= 1.0
* @return from, blended towards to. Hue, chroma, and tone will change.
*/
fun cam16Ucs(from: Int, to: Int, amount: Double): Int {
public fun cam16Ucs(from: Int, to: Int, amount: Double): Int {
val fromCam = Cam16.fromInt(from)
val toCam = Cam16.fromInt(to)
val fromJ = fromCam.jstar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@ import kotlin.math.max
* becomes HCT's tone and L*a*b*'s' L*.
*/
@Suppress("unused", "MemberVisibilityCanBePrivate")
object Contrast {
public object Contrast {

// The minimum contrast ratio of two colors.
// Contrast ratio equation = lighter + 5 / darker + 5, if lighter == darker, ratio == 1.
const val RATIO_MIN = 1.0
private const val RATIO_MIN = 1.0

// The maximum contrast ratio of two colors.
// Contrast ratio equation = lighter + 5 / darker + 5. Lighter and darker scale from 0 to 100.
// If lighter == 100, darker = 0, ratio == 21.
const val RATIO_MAX = 21.0
const val RATIO_30 = 3.0
const val RATIO_45 = 4.5
const val RATIO_70 = 7.0
private const val RATIO_MAX = 21.0
private const val RATIO_30 = 3.0
private const val RATIO_45 = 4.5
private const val RATIO_70 = 7.0

// Given a color and a contrast ratio to reach, the luminance of a color that reaches that ratio
// with the color can be calculated. However, that luminance may not contrast as desired, i.e. the
Expand Down Expand Up @@ -92,7 +92,7 @@ object Contrast {
*
* The equation is ratio = lighter Y + 5 / darker Y + 5.
*/
fun ratioOfYs(y1: Double, y2: Double): Double {
public fun ratioOfYs(y1: Double, y2: Double): Double {
val lighter: Double = max(y1, y2)
val darker = if (lighter == y2) y1 else y2
return (lighter + 5.0) / (darker + 5.0)
Expand All @@ -113,7 +113,7 @@ object Contrast {
* color's lightness to in order to reach their desired contrast, instead of guessing & checking
* with hex codes.
*/
fun ratioOfTones(tone1: Double, tone2: Double): Double {
public fun ratioOfTones(tone1: Double, tone2: Double): Double {
return ratioOfYs(yFromLstar(tone1), yFromLstar(tone2))
}

Expand All @@ -124,7 +124,7 @@ object Contrast {
* @param tone Tone return value must contrast with.
* @param ratio Desired contrast ratio of return value and tone parameter.
*/
fun lighter(tone: Double, ratio: Double): Double {
public fun lighter(tone: Double, ratio: Double): Double {
if (tone < 0.0 || tone > 100.0) {
return -1.0
}
Expand Down Expand Up @@ -155,7 +155,7 @@ object Contrast {
* @param tone Tone return value must contrast with.
* @param ratio Desired contrast ratio of return value and tone parameter.
*/
fun lighterUnsafe(tone: Double, ratio: Double): Double {
public fun lighterUnsafe(tone: Double, ratio: Double): Double {
val lighterSafe = lighter(tone, ratio)
return if (lighterSafe < 0.0) 100.0 else lighterSafe
}
Expand All @@ -167,7 +167,7 @@ object Contrast {
* @param tone Tone return value must contrast with.
* @param ratio Desired contrast ratio of return value and tone parameter.
*/
fun darker(tone: Double, ratio: Double): Double {
public fun darker(tone: Double, ratio: Double): Double {
if (tone < 0.0 || tone > 100.0) {
return -1.0
}
Expand Down Expand Up @@ -200,7 +200,7 @@ object Contrast {
* @param tone Tone return value must contrast with.
* @param ratio Desired contrast ratio of return value and tone parameter.
*/
fun darkerUnsafe(tone: Double, ratio: Double): Double {
public fun darkerUnsafe(tone: Double, ratio: Double): Double {
val darkerSafe = darker(tone, ratio)
return max(0.0, darkerSafe)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,24 @@ import kotlin.math.round
* Psychology (2015).
*/
@Suppress("MemberVisibilityCanBePrivate")
object DislikeAnalyzer {
public object DislikeAnalyzer {

/**
* Returns true if color is disliked.
*
* Disliked is defined as a dark yellow-green that is not neutral.
*/
fun isDisliked(hct: Hct): Boolean {
public fun isDisliked(hct: Hct): Boolean {
val huePasses = round(hct.hue) in 90.0..111.0
val chromaPasses: Boolean = round(hct.chroma) > 16.0
val tonePasses: Boolean = round(hct.tone) < 65.0
return huePasses && chromaPasses && tonePasses
}

/** If color is disliked, lighten it to make it likable. */
fun fixIfDisliked(hct: Hct): Hct {
return if (isDisliked(hct)) {
Hct.from(hct.hue, hct.chroma, 70.0)
} else hct
/**
* If color is disliked, lighten it to make it likable.
*/
public fun fixIfDisliked(hct: Hct): Hct {
return if (isDisliked(hct)) Hct.from(hct.hue, hct.chroma, 70.0) else hct
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import com.materialkolor.utils.MathUtils.lerp
* @param medium Value for contrast level 0.5
* @param high Value for contrast level 1.0
*/
class ContrastCurve(
public class ContrastCurve(
private val low: Double,
private val normal: Double,
private val medium: Double,
Expand All @@ -44,7 +44,7 @@ class ContrastCurve(
* is the highest.
* @return The value. For contrast ratios, a number between 1.0 and 21.0.
*/
fun get(contrastLevel: Double): Double = when {
public fun get(contrastLevel: Double): Double = when {
contrastLevel <= -1.0 -> low
contrastLevel < 0.0 -> lerp(low, normal, (contrastLevel - -1) / 1)
contrastLevel < 0.5 -> lerp(normal, medium, (contrastLevel - 0) / 0.5)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,16 @@ import kotlin.math.round
* @param opacity A function returning the opacity of a color, as a number between 0 and 1.
*/
@Suppress("MemberVisibilityCanBePrivate", "unused")
class DynamicColor(
val name: String,
val palette: (DynamicScheme) -> TonalPalette,
val tone: (DynamicScheme) -> Double,
val isBackground: Boolean,
val background: ((DynamicScheme) -> DynamicColor)?,
val secondBackground: ((DynamicScheme) -> DynamicColor)?,
val contrastCurve: ContrastCurve?,
val toneDeltaPair: ((DynamicScheme) -> ToneDeltaPair)?,
val opacity: ((DynamicScheme) -> Double)? = null,
public class DynamicColor(
public val name: String,
public val palette: (DynamicScheme) -> TonalPalette,
public val tone: (DynamicScheme) -> Double,
public val isBackground: Boolean,
public val background: ((DynamicScheme) -> DynamicColor)?,
public val secondBackground: ((DynamicScheme) -> DynamicColor)?,
public val contrastCurve: ContrastCurve?,
public val toneDeltaPair: ((DynamicScheme) -> ToneDeltaPair)?,
public val opacity: ((DynamicScheme) -> Double)? = null,
) {

private val hctCache: HashMap<DynamicScheme, Hct> = HashMap()
Expand All @@ -91,7 +91,7 @@ class DynamicColor(
* @param scheme Defines the conditions of the user interface, for example, whether or not it is
* dark mode or light mode, and what the desired contrast level is.
*/
fun getArgb(scheme: DynamicScheme): Int {
public fun getArgb(scheme: DynamicScheme): Int {
val argb: Int = getHct(scheme).toInt()
if (opacity == null) {
return argb
Expand All @@ -107,7 +107,7 @@ class DynamicColor(
* @param scheme Defines the conditions of the user interface, for example, whether or not it is
* dark mode or light mode, and what the desired contrast level is.
*/
fun getHct(scheme: DynamicScheme): Hct {
public fun getHct(scheme: DynamicScheme): Hct {
val cachedAnswer = hctCache[scheme]
if (cachedAnswer != null) {
return cachedAnswer
Expand All @@ -132,7 +132,7 @@ class DynamicColor(
/**
* Returns the tone in HCT, ranging from 0 to 100, of the resolved color given scheme.
*/
fun getTone(scheme: DynamicScheme): Double {
public fun getTone(scheme: DynamicScheme): Double {
val decreasingContrast: Boolean = scheme.contrastLevel < 0

// Case 1: dual foreground, pair of colors with delta constraint.
Expand Down Expand Up @@ -279,7 +279,7 @@ class DynamicColor(
}
}

companion object {
public companion object {

/**
* A convenience constructor for DynamicColor.
Expand All @@ -302,7 +302,7 @@ class DynamicColor(
* a tonal palette, when contrast adjustments are made, intended chroma can be preserved.
* @param tone Function that provides a tone, given a DynamicScheme.
*/
fun fromPalette(
public fun fromPalette(
name: String,
palette: (DynamicScheme) -> TonalPalette,
tone: (DynamicScheme) -> Double,
Expand Down Expand Up @@ -340,7 +340,7 @@ class DynamicColor(
* @param isBackground Whether this dynamic color is a background, with some other color as the
* foreground.
*/
fun fromPalette(
public fun fromPalette(
name: String,
palette: (DynamicScheme) -> TonalPalette,
tone: (DynamicScheme) -> Double,
Expand All @@ -364,7 +364,7 @@ class DynamicColor(
* @param name The name of the dynamic color.
* @param argb The source color from which to extract the hue and chroma.
*/
fun fromArgb(name: String, argb: Int): DynamicColor {
public fun fromArgb(name: String, argb: Int): DynamicColor {
val hct: Hct = Hct.fromInt(argb)
val palette = TonalPalette.fromInt(argb)
return fromPalette(name, { palette }, { hct.tone })
Expand All @@ -374,7 +374,7 @@ class DynamicColor(
* Given a background tone, find a foreground tone, while ensuring they reach a contrast ratio
* that is as close to ratio as possible.
*/
fun foregroundTone(bgTone: Double, ratio: Double): Double {
public fun foregroundTone(bgTone: Double, ratio: Double): Double {
val lighterTone: Double = Contrast.lighterUnsafe(bgTone, ratio)
val darkerTone: Double = Contrast.darkerUnsafe(bgTone, ratio)
val lighterRatio: Double = Contrast.ratioOfTones(lighterTone, bgTone)
Expand Down Expand Up @@ -403,7 +403,7 @@ class DynamicColor(
* Adjust a tone down such that white has 4.5 contrast, if the tone is reasonably close to
* supporting it.
*/
fun enableLightForeground(tone: Double): Double {
public fun enableLightForeground(tone: Double): Double {
return if (tonePrefersLightForeground(tone) && !toneAllowsLightForeground(tone)) 49.0
else tone
}
Expand All @@ -418,9 +418,9 @@ class DynamicColor(
* Since `tertiaryContainer` in dark monochrome scheme requires a tone of 60, it should not be
* adjusted. Therefore, 60 is excluded here.
*/
fun tonePrefersLightForeground(tone: Double): Boolean = round(tone) < 60
public fun tonePrefersLightForeground(tone: Double): Boolean = round(tone) < 60

/** Tones less than ~T50 always permit white at 4.5 contrast. */
fun toneAllowsLightForeground(tone: Double): Boolean = round(tone) <= 49
public fun toneAllowsLightForeground(tone: Double): Boolean = round(tone) <= 49
}
}
Loading

0 comments on commit fc9c52e

Please sign in to comment.