From 53f01d46097417355f0d283c51a3d5492f8efeb8 Mon Sep 17 00:00:00 2001 From: GibsonRuitiari Date: Wed, 27 Jul 2022 17:57:34 +0300 Subject: [PATCH 01/13] Upgraded espresso version, AboutScreenTest passes. --- .../main/java/com/android254/presentation/common/theme/Theme.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/presentation/src/main/java/com/android254/presentation/common/theme/Theme.kt b/presentation/src/main/java/com/android254/presentation/common/theme/Theme.kt index e326b3d..5cbd085 100644 --- a/presentation/src/main/java/com/android254/presentation/common/theme/Theme.kt +++ b/presentation/src/main/java/com/android254/presentation/common/theme/Theme.kt @@ -111,7 +111,7 @@ fun DroidconKE2022Theme( val activity = view.context.findActivity() // although view.context in compose is gotten from LocalContext.current the fetched context might not be the // closest activity in the given context thus making this method [not that] lack of a better word safe - // (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb() + //see https://gist.github.com/GibsonRuitiari/7cb947228661993ee36d5c05b9e8f23f activity.window.statusBarColor = colorScheme.primary.toArgb() // Using this method might return if the function fails to find window associated with the given activity's context // ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme From c7aca464f50b0a88a8b6809a31d1065c74f68f9c Mon Sep 17 00:00:00 2001 From: GibsonRuitiari Date: Wed, 27 Jul 2022 19:06:02 +0300 Subject: [PATCH 02/13] Upgraded espresso version, AboutScreenTest passes. --- .../java/com/android254/presentation/common/theme/Theme.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/presentation/src/main/java/com/android254/presentation/common/theme/Theme.kt b/presentation/src/main/java/com/android254/presentation/common/theme/Theme.kt index 5cbd085..da52b0b 100644 --- a/presentation/src/main/java/com/android254/presentation/common/theme/Theme.kt +++ b/presentation/src/main/java/com/android254/presentation/common/theme/Theme.kt @@ -111,10 +111,8 @@ fun DroidconKE2022Theme( val activity = view.context.findActivity() // although view.context in compose is gotten from LocalContext.current the fetched context might not be the // closest activity in the given context thus making this method [not that] lack of a better word safe - //see https://gist.github.com/GibsonRuitiari/7cb947228661993ee36d5c05b9e8f23f + //see https://gist.github.com/GibsonRuitiari/7cb947228661993ee36d5c05b9e8f23f for a detailed explanat activity.window.statusBarColor = colorScheme.primary.toArgb() - // Using this method might return if the function fails to find window associated with the given activity's context - // ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme WindowCompat.getInsetsController(activity.window, view).isAppearanceLightStatusBars = darkTheme } } From 5d4040a65f8cdb57d31d2914be7536450a0abcd3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Jul 2022 16:06:30 +0000 Subject: [PATCH 03/13] contrib-readme-action has updated readme --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fc11b12..93e5697 100644 --- a/README.md +++ b/README.md @@ -113,14 +113,21 @@ We would endlessly like to thank the following contributors Keith Chad + + + GibsonRuitiari +
+ 8BitsLives .❤️ +
+ + michaelbukachi
Michael Bukachi
- - + kibettheophilus From 34e609ddd8379609f037362f9a45c38a96f282c5 Mon Sep 17 00:00:00 2001 From: GibsonRuitiari Date: Fri, 16 Sep 2022 15:47:43 +0300 Subject: [PATCH 04/13] added ChaiColor --- .../java/com/droidconke/chai/atoms/Color.kt | 240 ++++++++++++++++++ .../com/droidconke/chai/components/CText.kt | 5 + .../java/com/droidconke/chai/utils/spec.kt | 17 ++ 3 files changed, 262 insertions(+) create mode 100644 chai/src/main/java/com/droidconke/chai/utils/spec.kt diff --git a/chai/src/main/java/com/droidconke/chai/atoms/Color.kt b/chai/src/main/java/com/droidconke/chai/atoms/Color.kt index cc455e7..1a9f6b1 100644 --- a/chai/src/main/java/com/droidconke/chai/atoms/Color.kt +++ b/chai/src/main/java/com/droidconke/chai/atoms/Color.kt @@ -15,7 +15,14 @@ */ package com.droidconke.chai.atoms +import androidx.compose.animation.core.* +import androidx.compose.runtime.* import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.colorspace.ColorSpace +import androidx.compose.ui.graphics.colorspace.ColorSpaces +import com.droidconke.chai.utils.chaiAnimationSpec +import kotlin.math.pow +import kotlin.reflect.KProperty /** * these are the Primary colours from Chai's Design spec document @@ -43,6 +50,239 @@ val ChaiDarkerGrey = Color(0xFF191d1d) val ChaiCoal = Color(0xFF20201E) val ChaiBlack = Color(0xFF000000) +/** + * Defines the colors to be used by the app + * This an abstraction that contains all the colors (neutrals,primary & secondary) + * needed by the application + * A normal class, instead of data class, is used to prevent changing of the colors via copy + * as that would lead to breaking of the intended app design system + * Note: The color definition ought to be in Hex Color format + * @param value the color value given by the client, the value is of a type [Color] + */ +@Immutable // since we are using an internal constructor, values read from [ChaiColor] won't change after an instance is constructed +@JvmInline +value class ChaiColor internal constructor(val value:Color){ + /** + * Changes the alpha of the ChaiColor + * @param alpha alpha in form float to be applied to current ChaiColor + * @return an instance of ChaiColor with modified alpha value + */ + fun changeAlpha(alpha:Float) = ChaiColor(value.copy(alpha=alpha)) + + companion object{ + // should not be used in real components but, + // can be used as a base value for ChaiColor + @Stable + internal val Unspecified = ChaiColor(value = Color.Unspecified) + + /* these are the Primary colours from Chai's Design spec document*/ + @Stable + val ChaiBlue = ChaiColor(value=Color(0xFF000CEB)) + @Stable + val ChaiWhite = ChaiColor(value = Color(0xFFFFFFFF)) + + /* these are the Secondary colours from Chai's Design spec document */ + @Stable + val ChaiRed = ChaiColor(value=Color(0xFFFF6E4D)) + @Stable + val ChaiTeal = ChaiColor(value=Color(0xFF00e2c3)) + @Stable + val ChaiFadedLime = ChaiColor(value=Color(0xFF7de1c3)) + + /* these are the Neutrals from the Chai's Design spec document */ + @Stable + val ChaiLightGrey = ChaiColor(value=Color(0xFFF5F5F5)) + @Stable + val ChaiGrey = ChaiColor(value=Color(0xFFB1B1B1)) + @Stable + val ChaiDarkGrey = ChaiColor(value=Color(0xFF5A5A5A)) + @Stable + val ChaiDarkerGrey =ChaiColor(value= Color(0xFF191d1d)) + @Stable + val ChaiCoal = ChaiColor(value=Color(0xFF20201E)) + @Stable + val ChaiBlack = ChaiColor(value=Color(0xFF000000)) + + /** + * Typically colors are 3 dimensional planes i.e x,y,z + * with the x being red, y being green and z blue + * The three combined create a [ColorSpace] i.e a unique representation + * of colors that can be created by combining the three pigments + * To convert one color to the other, a mapping of these color spaces is needed + * from [xyz] plane to another [xyz] plane. + * for comprehensive explanation see [explanation] (https://en.wikipedia.org/wiki/Color_space) + * note: adapted from aosp + */ + private fun multiplyColumn(column:Int,x:Float,y:Float, + z:Float,matrix:FloatArray) = x*matrix[column]+y*matrix[3+column]+z*matrix[6+column] + private val M1 = floatArrayOf( + 0.80405736f, + 0.026893456f, + 0.04586542f, + 0.3188387f, + 0.9319606f, + 0.26299807f, + -0.11419419f, + 0.05105356f, + 0.83999807f, + ) + + private val InverseM1 = floatArrayOf( + 1.2485008f, + -0.032856926f, + -0.057883114f, + -0.48331892f, + 1.1044513f, + -0.3194066f, + 0.19910365f, + -0.07159331f, + 1.202023f, + ) + internal val VectorConverter: (colorSpace: ColorSpace) -> TwoWayConverter = + { colorSpace -> + TwoWayConverter( + convertToVector = { chaiColor -> + val color by chaiColor + val colorXyz = color.convert( + colorSpace = ColorSpaces.CieXyz, + ) + + val x = colorXyz.red + val y = colorXyz.green + val z = colorXyz.blue + + + val l = multiplyColumn( + column = 0, + x = x, + y = y, + z = z, + matrix = M1, + ).pow( + x = 1f / 3f, + ) + val a = multiplyColumn( + column = 1, + x = x, + y = y, + z = z, + matrix = M1, + ).pow( + x = 1f / 3f, + ) + val b = multiplyColumn( + column = 2, + x = x, + y = y, + z = z, + matrix = M1, + ).pow( + x = 1f / 3f, + ) + + AnimationVector4D( + v1 = color.alpha, + v2 = l, + v3 = a, + v4 = b, + ) + }, + convertFromVector = { vector -> + val l = vector.v2.pow( + x = 3f, + ) + val a = vector.v3.pow( + x = 3f, + ) + val b = vector.v4.pow( + x = 3f, + ) + + val x = multiplyColumn( + column = 0, + x = l, + y = a, + z = b, + matrix = InverseM1, + ) + val y = multiplyColumn( + column = 1, + x = l, + y = a, + z = b, + matrix = InverseM1, + ) + val z = multiplyColumn( + column = 2, + x = l, + y = a, + z = b, + matrix = InverseM1, + ) + + val colorXyz = Color( + alpha = vector.v1.coerceIn( + minimumValue = 0f, + maximumValue = 1f, + ), + red = x.coerceIn( + minimumValue = -2f, + maximumValue = 2f, + ), + green = y.coerceIn( + minimumValue = -2f, + maximumValue = 2f, + ), + blue = z.coerceIn( + minimumValue = -2f, + maximumValue = 2f, + ), + colorSpace = ColorSpaces.CieXyz, + ) + + ChaiColor( + value = colorXyz.convert( + colorSpace = colorSpace, + ), + ) + } + ) + } + } + operator fun getValue(thisRef:Any?,property:KProperty<*>) = value +} + +/** + * Constructs a color animation spec using [tween] + * The duration millis is divided by 2 since color animation + * more often than not will depend on other animations, + * so it needs to run and complete before other animations to ensure a + * smooth transition + * @receiver animation spec to be used, ideally should be an instance of [TweenSpec] + * @return a new instance of animation spec whose duration is divided by 2 + */ +private fun AnimationSpec.toColorSpec():AnimationSpec{ + val tweenSpec = this as TweenSpec ?: return this + return tween(durationMillis = tweenSpec.durationMillis/2, + delayMillis = tweenSpec.delay,easing=tweenSpec.easing) +} +/** + * This is supposed to be used to animate [ChaiColor] changes + * @param targetValue an instance of [ChaiColor] + * @param animationSpec animationSpec to be used when color change is detected/happens + * @return state object of type [ChaiColor] + */ +@Composable +internal fun animateChaiColorAsState(targetValue:ChaiColor,animationSpec: AnimationSpec = chaiAnimationSpec() +):State{ + val converter = remember(key1 = targetValue.value.colorSpace) { + (ChaiColor.VectorConverter)(targetValue.value.colorSpace) + } + return animateValueAsState(targetValue = targetValue, + typeConverter =converter, + animationSpec = animationSpec.toColorSpec(), + finishedListener = null) +} /** * TOBE Replaced */ diff --git a/chai/src/main/java/com/droidconke/chai/components/CText.kt b/chai/src/main/java/com/droidconke/chai/components/CText.kt index 5bc94c6..565ebc4 100644 --- a/chai/src/main/java/com/droidconke/chai/components/CText.kt +++ b/chai/src/main/java/com/droidconke/chai/components/CText.kt @@ -99,4 +99,9 @@ fun CActionText(cAction: String) { ), modifier = Modifier.fillMaxWidth() ) +} + +@Composable +internal fun ChaiText(modifier:Modifier=Modifier,text:String,singleLine:Boolean=true){ + } \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/utils/spec.kt b/chai/src/main/java/com/droidconke/chai/utils/spec.kt new file mode 100644 index 0000000..d078d2d --- /dev/null +++ b/chai/src/main/java/com/droidconke/chai/utils/spec.kt @@ -0,0 +1,17 @@ +package com.droidconke.chai.utils + +import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.tween +import androidx.compose.runtime.Stable + +/** + * Default duration time to be used in ChaiDesign system + */ +const val ChaiDefaultAnimationMillis=250 +/** + * Basic/default animation spec to be used by ChaiDesign system + * @return tween animation spec + */ +@Stable +internal fun chaiAnimationSpec() = tween(durationMillis= ChaiDefaultAnimationMillis, +easing = FastOutSlowInEasing) \ No newline at end of file From 5b082191c660735005683b26f0b899982c3c5db6 Mon Sep 17 00:00:00 2001 From: GibsonRuitiari Date: Fri, 16 Sep 2022 18:05:03 +0300 Subject: [PATCH 05/13] added animation utility methods and ChaiDesignText + ChaiDesignIcon --- .../java/com/droidconke/chai/atoms/Color.kt | 1 + .../com/droidconke/chai/components/CText.kt | 29 +++- .../droidconke/chai/components/CTextStyle.kt | 125 ++++++++++++++++++ .../java/com/droidconke/chai/icons/Icons.kt | 31 ++++- .../droidconke/chai/utils/animateAsState.kt | 32 +++++ 5 files changed, 213 insertions(+), 5 deletions(-) create mode 100644 chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt create mode 100644 chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt diff --git a/chai/src/main/java/com/droidconke/chai/atoms/Color.kt b/chai/src/main/java/com/droidconke/chai/atoms/Color.kt index 1a9f6b1..36f89ed 100644 --- a/chai/src/main/java/com/droidconke/chai/atoms/Color.kt +++ b/chai/src/main/java/com/droidconke/chai/atoms/Color.kt @@ -57,6 +57,7 @@ val ChaiBlack = Color(0xFF000000) * A normal class, instead of data class, is used to prevent changing of the colors via copy * as that would lead to breaking of the intended app design system * Note: The color definition ought to be in Hex Color format + * * Example usage see ChaiDemo * @param value the color value given by the client, the value is of a type [Color] */ @Immutable // since we are using an internal constructor, values read from [ChaiColor] won't change after an instance is constructed diff --git a/chai/src/main/java/com/droidconke/chai/components/CText.kt b/chai/src/main/java/com/droidconke/chai/components/CText.kt index 565ebc4..45c9620 100644 --- a/chai/src/main/java/com/droidconke/chai/components/CText.kt +++ b/chai/src/main/java/com/droidconke/chai/components/CText.kt @@ -18,11 +18,14 @@ package com.droidconke.chai.components import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp -import com.droidconke.chai.atoms.* +import com.droidconke.chai.atoms.ChaiBlack +import com.droidconke.chai.atoms.ChaiBlue +import com.droidconke.chai.atoms.ChaiRed import com.droidconke.chai.atoms.type.MontserratRegular import com.droidconke.chai.atoms.type.MontserratThin @@ -39,6 +42,27 @@ import com.droidconke.chai.atoms.type.MontserratThin * * */ +/** + * Basic Text Construct, that adheres to the app's design system, + * which is to be used by clients whenever they need + * a text component in their composables + * @param modifier modifier to be applied to the text component + * @param style ChaiTextStyle design to be applied, note the design includes + * the font-family+weight, color, and text size + * @param singleLine whether this text is a single line + */ +@Composable +internal fun ChaiText(modifier: Modifier=Modifier,text:String, +style: ChaiTextStyle,singleLine:Boolean=true){ + val styleAnimationState by animateChaiTextStyleAsState(targetValue = style) + Text(text = text, style = styleAnimationState.asComposedStyle(), + modifier = modifier, maxLines = when(singleLine){ + true->1 + else->Int.MAX_VALUE + }) +} + + /** * Title based fonts * */ @@ -101,7 +125,4 @@ fun CActionText(cAction: String) { ) } -@Composable -internal fun ChaiText(modifier:Modifier=Modifier,text:String,singleLine:Boolean=true){ -} \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt b/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt new file mode 100644 index 0000000..92105bc --- /dev/null +++ b/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt @@ -0,0 +1,125 @@ +package com.droidconke.chai.components + +import androidx.compose.animation.core.AnimationSpec +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.State +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.ExperimentalUnitApi +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.TextUnitType +import androidx.compose.ui.unit.sp +import com.droidconke.chai.R +import com.droidconke.chai.atoms.ChaiColor +import com.droidconke.chai.atoms.animateChaiColorAsState +import com.droidconke.chai.utils.animateChaiAsState +import com.droidconke.chai.utils.chaiAnimationSpec + +/** + * Defines the ChaiDesign system TextStyle + * This is the text style to be used by the client/across + * the app instead of [TextStyle]. (Maybe implement a custom lint warning to enforce this?) + * Example usage see ChaiDemo + * @param text color which is of type [ChaiColor] + * @param size text size + * @param weight text weight + * @param letterSpacing the spacing of letters + * @param textAlign TextAlignment by default is [TextAlign.Center] + */ +@Immutable +class ChaiTextStyle internal constructor(val color: ChaiColor = ChaiColor.ChaiBlack, + val size: TextUnit, + val weight: FontWeight, + val letterSpacing: TextUnit = 0.sp, + val fontFamily: FontFamily, + val textAlign: TextAlign = TextAlign.Center){ + /** + * Converts an instance of [ChaiTextStyle] into compose [TextStyle] + * @return text style + */ + @Stable + internal fun asComposedStyle() = TextStyle(color=color.value, + fontSize = size, fontWeight = weight, fontFamily = fontFamily, + letterSpacing = letterSpacing, textAlign = textAlign) + + companion object{ + // annotating the variables with @Stable because it is a much stronger contract than val + // note: compose compiler takes val to be unstable + @Stable + private val montserratRegular = FontFamily(Font(R.font.montserrat_regular)) + @Stable + private val montserratThin = FontFamily(Font(R.font.montserrat_thin)) + @Stable + val CActionStyle = ChaiTextStyle(color = ChaiColor.ChaiRed, size = 10.sp, + weight = FontWeight.W700, fontFamily = montserratRegular) + @Stable + val CSubtitleStyle = ChaiTextStyle(color= ChaiColor.ChaiRed,size=15.sp, + fontFamily = montserratRegular, weight = FontWeight.W700) + @Stable + val CParagraphStyle = ChaiTextStyle(color= ChaiColor.ChaiBlack, + size=12.sp, + fontFamily = montserratRegular, weight = FontWeight.W500) + @Stable + val CPageTitleStyle = ChaiTextStyle(color= ChaiColor.ChaiBlue, + size=33.sp, + fontFamily = montserratThin, weight = FontWeight.W300) + + } + + /** + * This method is appropriate for the times when a text style + * is constructed but some properties need to be changed + * @param color text color + * @param weight font weight + * @param textAlign alignment of text + * @param fontFamily font family used by text + * @return an instance of ChaiTextStyle + */ + @Stable + internal fun change(color: ChaiColor =this.color, + weight: FontWeight =this.weight, + textAlign: TextAlign =this.textAlign, + fontFamily: FontFamily =this.fontFamily) = ChaiTextStyle(color=color, + weight = weight, + letterSpacing = letterSpacing, + fontFamily = fontFamily, + size = size, textAlign = textAlign) + +} + +@OptIn(ExperimentalUnitApi::class) +@Stable +private fun Float.toSp() = TextUnit(value=this, type = TextUnitType.Sp) +/** + * A [ChaiTextStyle] properties animator + * Currently it animates only the [ChaiTextStyle.color] & [ChaiTextStyle.size] properties + * @param targetValue the [ChaiTextStyle] to be animated + * @param animationSpec animation spec to be used during the animation + * @return [targetValue] returns an animated [ChaiTextStyle] in form of [State] + */ +@Suppress("UNCHECKED_CAST") +@Composable +internal fun animateChaiTextStyleAsState(targetValue:ChaiTextStyle, + animationSpec: AnimationSpec = chaiAnimationSpec() +): State { + val targetColorAnimationState = animateChaiColorAsState(targetValue = targetValue.color, + animationSpec = animationSpec as AnimationSpec + ) + val targetSizeAnimationState = animateFloatAsState(targetValue = targetValue.size.value, + animationSpec= animationSpec as AnimationSpec + ) + return animateChaiAsState(initialValue = targetValue, + animationStates = listOf(targetColorAnimationState,targetSizeAnimationState), + targetBuilder = {animatedValues -> + val (color,size) = animatedValues + ChaiTextStyle(color= color as ChaiColor, size = (size as Float).toSp(), + weight = targetValue.weight, letterSpacing = targetValue.letterSpacing, textAlign = targetValue.textAlign, + fontFamily = targetValue.fontFamily) + }) +} \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/icons/Icons.kt b/chai/src/main/java/com/droidconke/chai/icons/Icons.kt index 6728353..8ed6ac9 100644 --- a/chai/src/main/java/com/droidconke/chai/icons/Icons.kt +++ b/chai/src/main/java/com/droidconke/chai/icons/Icons.kt @@ -13,4 +13,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.droidconke.chai.icons \ No newline at end of file +package com.droidconke.chai.icons + +import androidx.annotation.DrawableRes +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import com.droidconke.chai.R + +/** + * An abstraction that defines the icons to be used instead of + * accessing icon resources directly + * @param drawableId icon drawable resource id + */ +@Immutable +@JvmInline +value class ChaiIcon private constructor(@DrawableRes val drawableId:Int){ + companion object{ + @Stable + val About = ChaiIcon(drawableId = R.drawable.about_icon) + @Stable + val FeedIcon = ChaiIcon(drawableId = R.drawable.feed_icon) + @Stable + val HomeIcon = ChaiIcon(drawableId = R.drawable.home_icon) + @Stable + val SessionsIcon = ChaiIcon(drawableId = R.drawable.sessions_icon) + @Stable + val BackArrow = ChaiIcon(drawableId = R.drawable.ic_back_arrow) + @Stable + val GoogleIcon = ChaiIcon(drawableId = R.drawable.ic_google_logo_icon) + } +} \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt b/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt new file mode 100644 index 0000000..bb2685d --- /dev/null +++ b/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt @@ -0,0 +1,32 @@ +package com.droidconke.chai.utils + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.snapshotFlow +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine + +private fun State.toFlow() = snapshotFlow { this } + +/** + * Animates Chai's design properties, and returns a new instance + * of Chai's design property in form of a [State] + * @param initialValue initial value of the design resource/property must be of type ChaiDesign eg ChaiIcon + * @param animationStates a list of animation states which are created from [animate*AsState] functions + * @param targetBuilder a function that takes in a list of animated design properties and returns a single + * value of type ChaiDesign (of type [T]) eg ChaiIcon wrapped in [State] + * @return an animated state which is an instance ChaiDesign wrapped in [State] + */ +@Composable +internal inline fun animateChaiAsState(initialValue:T,animationStates:List>, + crossinline targetBuilder:(animatedValues:List)->T):State{ + val animationFlows:List> = animationStates.map(State<*>::toFlow) + // (combine scales linearly; find a better option probably)? + return combine(flows=animationFlows){_animationFlows-> + targetBuilder(_animationFlows.mapIndexed { index, flow -> (flow as State<*>).value ?: + throw NullPointerException("animation of the individual element at index $index of type " + + "is null hence cannot be animated")}) + }.collectAsState(initial = initialValue) + +} \ No newline at end of file From 5d5eb44280c971ddfb5dea41d058f38740208cf9 Mon Sep 17 00:00:00 2001 From: GibsonRuitiari Date: Fri, 16 Sep 2022 18:46:48 +0300 Subject: [PATCH 06/13] added ChaiDesign image component used with icons/drawables --- .../java/com/droidconke/chai/atoms/Color.kt | 4 +- .../com/droidconke/chai/components/CText.kt | 162 +++++++++++------- .../java/com/droidconke/chai/images/Images.kt | 38 +++- .../com/droidconke/chai/modifier/clickable.kt | 37 ++++ .../droidconke/chai/utils/AnimateContent.kt | 37 ++++ .../java/com/droidconke/chaidemo/ChaiDemo.kt | 6 +- .../droidconke/chaidemo/screens/TextDemo.kt | 16 +- 7 files changed, 228 insertions(+), 72 deletions(-) create mode 100644 chai/src/main/java/com/droidconke/chai/modifier/clickable.kt create mode 100644 chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt diff --git a/chai/src/main/java/com/droidconke/chai/atoms/Color.kt b/chai/src/main/java/com/droidconke/chai/atoms/Color.kt index 36f89ed..e49f756 100644 --- a/chai/src/main/java/com/droidconke/chai/atoms/Color.kt +++ b/chai/src/main/java/com/droidconke/chai/atoms/Color.kt @@ -111,7 +111,7 @@ value class ChaiColor internal constructor(val value:Color){ * of colors that can be created by combining the three pigments * To convert one color to the other, a mapping of these color spaces is needed * from [xyz] plane to another [xyz] plane. - * for comprehensive explanation see [explanation] (https://en.wikipedia.org/wiki/Color_space) + * for comprehensive explanation see [full_explanation] (https://en.wikipedia.org/wiki/Color_space) * note: adapted from aosp */ private fun multiplyColumn(column:Int,x:Float,y:Float, @@ -268,7 +268,7 @@ private fun AnimationSpec.toColorSpec():AnimationSpec{ delayMillis = tweenSpec.delay,easing=tweenSpec.easing) } /** - * This is supposed to be used to animate [ChaiColor] changes + * Animates [ChaiColor] changes from one color to the other * @param targetValue an instance of [ChaiColor] * @param animationSpec animationSpec to be used when color change is detected/happens * @return state object of type [ChaiColor] diff --git a/chai/src/main/java/com/droidconke/chai/components/CText.kt b/chai/src/main/java/com/droidconke/chai/components/CText.kt index 45c9620..5b4f713 100644 --- a/chai/src/main/java/com/droidconke/chai/components/CText.kt +++ b/chai/src/main/java/com/droidconke/chai/components/CText.kt @@ -15,19 +15,13 @@ */ package com.droidconke.chai.components -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.NonRestartableComposable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp -import com.droidconke.chai.atoms.ChaiBlack -import com.droidconke.chai.atoms.ChaiBlue -import com.droidconke.chai.atoms.ChaiRed -import com.droidconke.chai.atoms.type.MontserratRegular -import com.droidconke.chai.atoms.type.MontserratThin +import com.droidconke.chai.atoms.ChaiColor +import com.droidconke.chai.utils.AnimateContentChange /** * CText: @@ -42,6 +36,8 @@ import com.droidconke.chai.atoms.type.MontserratThin * * */ + + /** * Basic Text Construct, that adheres to the app's design system, * which is to be used by clients whenever they need @@ -61,68 +57,114 @@ style: ChaiTextStyle,singleLine:Boolean=true){ else->Int.MAX_VALUE }) } +/** + * Basic Text Construct that construct an animated text, and adheres to the app's design system, + * This is to be used by clients whenever they need a text component in their composables + * @param modifier modifier to be applied to the text component + * @param style ChaiTextStyle design to be applied, note the design includes + * the font-family+weight, color, and text size + * @param singleLine whether this text is a single line + */ +@Composable +internal fun AnimatedChaiText(modifier: Modifier=Modifier, + text: String, + style: ChaiTextStyle, + singleLine: Boolean=true){ + val styleAnimationState by animateChaiTextStyleAsState(targetValue = style) + AnimateContentChange(targetState = text, modifier = modifier) {animatedText-> + Text(text = animatedText, style = styleAnimationState.asComposedStyle(),maxLines = when(singleLine){ + true->1 + else->Int.MAX_VALUE + }) + } +} /** * Title based fonts * */ -@Composable -fun CParagraph(dParagraph: String) { - Text( - text = dParagraph, - style = TextStyle( - color = ChaiBlack, - fontSize = 12.sp, - fontWeight = FontWeight.W500, - fontFamily = MontserratRegular, - ), - modifier = Modifier.fillMaxWidth() - ) -} @Composable -fun CPageTitle(pageTitle: String) { - Text( - text = pageTitle, - style = TextStyle( - color = ChaiBlue, - fontSize = 33.sp, - fontWeight = FontWeight.W300, - fontFamily = MontserratThin, - - ), - modifier = Modifier.fillMaxWidth() - ) -} +@NonRestartableComposable +fun ChaiParagraph(modifier: Modifier=Modifier, + text:String, + color: ChaiColor = ChaiColor.ChaiBlack)= ChaiText( + modifier=modifier, + text = text, + style = ChaiTextStyle.CParagraphStyle.change(color=color) +) @Composable -fun CSubtitle(dSubtitle: String) { - Text( - text = dSubtitle, - style = TextStyle( - color = ChaiRed, - fontSize = 15.sp, - fontWeight = FontWeight.W700, - fontFamily = MontserratRegular, - - ), - modifier = Modifier.fillMaxWidth() - ) -} +@NonRestartableComposable +fun ChaiPageTitle(modifier:Modifier=Modifier, + text: String, + color: ChaiColor = ChaiColor.ChaiCoal) = AnimatedChaiText( + text = text, + modifier=modifier, + style = ChaiTextStyle.CPageTitleStyle.change(color=color)) @Composable -fun CActionText(cAction: String) { - Text( - text = cAction, - style = TextStyle( - color = ChaiRed, - fontSize = 15.sp, - fontWeight = FontWeight.W700, - fontFamily = MontserratRegular, +@NonRestartableComposable +fun ChaiSubtitle(modifier: Modifier=Modifier,text: String,color: ChaiColor= ChaiColor.ChaiBlack) = + ChaiText(text = text, modifier = modifier, style= ChaiTextStyle.CSubtitleStyle.change(color=color) ) - ), - modifier = Modifier.fillMaxWidth() - ) -} +//@Composable +//fun CParagraph(dParagraph: String) { +// Text( +// text = dParagraph, +// style = TextStyle( +// color = ChaiBlack, +// fontSize = 12.sp, +// fontWeight = FontWeight.W500, +// fontFamily = MontserratRegular, +// ), +// modifier = Modifier.fillMaxWidth() +// ) +//} +// +//@Composable +//fun CPageTitle(pageTitle: String) { +// Text( +// text = pageTitle, +// style = TextStyle( +// color = ChaiBlue, +// fontSize = 33.sp, +// fontWeight = FontWeight.W300, +// fontFamily = MontserratThin, +// +// ), +// modifier = Modifier.fillMaxWidth() +// ) +//} +// +//@Composable +//fun CSubtitle(dSubtitle: String) { +// Text( +// text = dSubtitle, +// style = TextStyle( +// color = ChaiRed, +// fontSize = 15.sp, +// fontWeight = FontWeight.W700, +// fontFamily = MontserratRegular, +// +// ), +// modifier = Modifier.fillMaxWidth() +// ) +//} +// +//@Composable +//fun CActionText(cAction: String) { +// Text( +// text = cAction, +// style = TextStyle( +// color = ChaiRed, +// fontSize = 15.sp, +// fontWeight = FontWeight.W700, +// fontFamily = MontserratRegular, +// +// ), +// modifier = Modifier.fillMaxWidth() +// ) +//} diff --git a/chai/src/main/java/com/droidconke/chai/images/Images.kt b/chai/src/main/java/com/droidconke/chai/images/Images.kt index c51d0ef..2467cf2 100644 --- a/chai/src/main/java/com/droidconke/chai/images/Images.kt +++ b/chai/src/main/java/com/droidconke/chai/images/Images.kt @@ -13,4 +13,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.droidconke.chai.images \ No newline at end of file +package com.droidconke.chai.images + +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.runtime.Composable +import androidx.compose.runtime.NonRestartableComposable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.res.painterResource +import com.droidconke.chai.atoms.ChaiColor +import com.droidconke.chai.icons.ChaiIcon +import com.droidconke.chai.modifier.chaiClickable + +/** + * An image component that uses icons + * + * @param icon to be used which is a drawable + * @param tint tint color to be applied to the icon + * @param contentDescription content description of the icon + * @param rippleEnabled whether ripple animation is enabled + * @param onClick on click listener attached to this image component + */ +@Composable +@NonRestartableComposable +fun ChaiImage(icon:ChaiIcon?, + tint:ChaiColor?=null, + contentDescription:String?=null, + rippleEnabled:Boolean=true,onClick:(()->Unit)?=null){ + if (icon==null) return + Image(modifier = Modifier.chaiClickable(rippleEnabled=rippleEnabled, + onClick = onClick), + painter =painterResource(id = icon.drawableId), + contentDescription =contentDescription, + colorFilter = tint.toColorFilter()) +} + +private fun ChaiColor?.toColorFilter() = this?.run { ColorFilter.tint(color=value) } \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt b/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt new file mode 100644 index 0000000..6a5a1de --- /dev/null +++ b/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt @@ -0,0 +1,37 @@ +package com.droidconke.chai.modifier + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.indication +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.runtime.Stable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import com.droidconke.chai.atoms.ChaiColor + + +/** + * Modifier that can be used to make components clickable + * @param onClick the listener to be used when component is clicked + * @param rippleColor ripple color to be used when component is clicked + * @param rippleEnabled whether or not ripple animation/effect is enabled + * by default it is + * @return clickable modifier + */ +@Stable +internal fun Modifier.chaiClickable( + rippleEnabled:Boolean=true, + rippleColor:ChaiColor?=null, + onClick: (()->Unit)?) = when(onClick!=null){ + true->composed { + clickable(onClick = onClick, + indication = rememberRipple( + color = rippleColor?.value ?: ChaiColor.Unspecified.value, + ).takeIf { + rippleEnabled + }, + interactionSource = remember { MutableInteractionSource() }) + } + else->this + } \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt b/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt new file mode 100644 index 0000000..c473d76 --- /dev/null +++ b/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt @@ -0,0 +1,37 @@ +package com.droidconke.chai.utils + +import androidx.compose.animation.* +import androidx.compose.animation.core.AnimationSpec +import androidx.compose.animation.core.FiniteAnimationSpec +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.IntSize + + +/** + * Function which animates content change whenever state of a composable state + *@param targetState composable's state to watch for changes + *@param content content to be shown by AnimatedContent container + *@param animationSpec animation spec to be used by default chaiAnimationSpec is used + */ +@Suppress("UNCHECKED_CAST") +@OptIn(ExperimentalAnimationApi::class) +@Composable +internal fun AnimateContentChange(modifier:Modifier=Modifier, + targetState:T, animationSpec:AnimationSpec = chaiAnimationSpec(), + content:@Composable AnimatedVisibilityScope.(animatedTargetState:T)->Unit +){ + AnimatedContent(targetState = targetState, modifier = modifier,content=content, + transitionSpec = { + fadeIn( + animationSpec = animationSpec as FiniteAnimationSpec, + ) with fadeOut( + animationSpec = animationSpec as FiniteAnimationSpec, + ) using SizeTransform( + clip = false, + sizeAnimationSpec = { _, _ -> + animationSpec as FiniteAnimationSpec + }, + ) + }) +} \ No newline at end of file diff --git a/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt b/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt index 5859fe7..649c24f 100644 --- a/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt +++ b/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt @@ -39,11 +39,11 @@ fun ChaiDemo() { .padding(horizontal = 13.dp, vertical = 5.dp) ) { BreathingSpace26() - CPageTitle("Chai Demo") + ChaiPageTitle(text ="Chai Demo" ) SeparatorSpace() - CSubtitle("A catalog of the chai design system elements") + ChaiSubtitle(text="A catalog of the chai design system elements") SeparatorSpace() - CParagraph("Check the code that is with each view") + ChaiParagraph(text="Check the code that is with each view") BreathingSpace13() } } diff --git a/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt b/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt index c0e4900..8d36520 100644 --- a/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt +++ b/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt @@ -19,15 +19,18 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.droidconke.chai.ChaiDCKE22Theme import com.droidconke.chai.atoms.ChaiWhite -import com.droidconke.chai.components.CPageTitle -import com.droidconke.chai.components.CParagraph -import com.droidconke.chai.components.CSubtitle +import com.droidconke.chai.components.* +import com.droidconke.chai.icons.ChaiIcon import com.droidconke.chai.utils.BreathingSpace13 import com.droidconke.chai.utils.BreathingSpace26 import com.droidconke.chai.utils.SeparatorSpace @@ -44,12 +47,13 @@ fun TextScreen() { .padding(horizontal = 13.dp, vertical = 5.dp) ) { BreathingSpace26() - CPageTitle("Welcome Message") + ChaiPageTitle(text="Welcome Message") SeparatorSpace() - CSubtitle("dcke 2022 welcome remarks as subtitle") + ChaiSubtitle(text="dcke 2022 welcome remarks as subtitle") SeparatorSpace() - CParagraph("Welcome to droidconKE 2022. Lorem something something") + ChaiParagraph(text="Welcome to droidconKE 2022. Lorem something something") BreathingSpace13() + IconButton(onClick = { /*TODO*/ }) { Icon(painter = painterResource(id = ChaiIcon.FeedIcon.drawableId), contentDescription = null)} } } } \ No newline at end of file From 3daf6fb6962bbb36a07c7e8c3a1149f72ca20bdc Mon Sep 17 00:00:00 2001 From: GibsonRuitiari Date: Fri, 16 Sep 2022 19:04:15 +0300 Subject: [PATCH 07/13] added ChaiDesign image component used with icons/drawables --- chai/src/main/java/com/droidconke/chai/images/Images.kt | 5 +++-- chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt | 3 ++- .../main/java/com/droidconke/chaidemo/screens/TextDemo.kt | 6 +++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/chai/src/main/java/com/droidconke/chai/images/Images.kt b/chai/src/main/java/com/droidconke/chai/images/Images.kt index 2467cf2..d12d876 100644 --- a/chai/src/main/java/com/droidconke/chai/images/Images.kt +++ b/chai/src/main/java/com/droidconke/chai/images/Images.kt @@ -37,12 +37,13 @@ import com.droidconke.chai.modifier.chaiClickable */ @Composable @NonRestartableComposable -fun ChaiImage(icon:ChaiIcon?, +fun ChaiImage(modifier: Modifier=Modifier, + icon:ChaiIcon?, tint:ChaiColor?=null, contentDescription:String?=null, rippleEnabled:Boolean=true,onClick:(()->Unit)?=null){ if (icon==null) return - Image(modifier = Modifier.chaiClickable(rippleEnabled=rippleEnabled, + Image(modifier = modifier.chaiClickable(rippleEnabled=rippleEnabled, onClick = onClick), painter =painterResource(id = icon.drawableId), contentDescription =contentDescription, diff --git a/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt b/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt index 649c24f..bef45d2 100644 --- a/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt +++ b/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.droidconke.chai.ChaiDCKE22Theme +import com.droidconke.chai.atoms.ChaiColor import com.droidconke.chai.atoms.ChaiWhite import com.droidconke.chai.components.* import com.droidconke.chai.utils.BreathingSpace13 @@ -35,7 +36,7 @@ fun ChaiDemo() { Column( Modifier .fillMaxSize() - .background(color = ChaiWhite) + .background(color = ChaiColor.ChaiWhite.value) .padding(horizontal = 13.dp, vertical = 5.dp) ) { BreathingSpace26() diff --git a/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt b/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt index 8d36520..4225d77 100644 --- a/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt +++ b/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt @@ -28,9 +28,11 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.droidconke.chai.ChaiDCKE22Theme +import com.droidconke.chai.atoms.ChaiColor import com.droidconke.chai.atoms.ChaiWhite import com.droidconke.chai.components.* import com.droidconke.chai.icons.ChaiIcon +import com.droidconke.chai.images.ChaiImage import com.droidconke.chai.utils.BreathingSpace13 import com.droidconke.chai.utils.BreathingSpace26 import com.droidconke.chai.utils.SeparatorSpace @@ -53,7 +55,9 @@ fun TextScreen() { SeparatorSpace() ChaiParagraph(text="Welcome to droidconKE 2022. Lorem something something") BreathingSpace13() - IconButton(onClick = { /*TODO*/ }) { Icon(painter = painterResource(id = ChaiIcon.FeedIcon.drawableId), contentDescription = null)} + ChaiImage(modifier=Modifier,icon=ChaiIcon.FeedIcon,tint = ChaiColor.ChaiDarkGrey) + BreathingSpace13() + IconButton(onClick = { }) { Icon(painter = painterResource(id = ChaiIcon.FeedIcon.drawableId), contentDescription = null)} } } } \ No newline at end of file From fb0bca77da24a9cf41963f78f38b6190591e26e6 Mon Sep 17 00:00:00 2001 From: GibsonRuitiari Date: Fri, 16 Sep 2022 19:06:52 +0300 Subject: [PATCH 08/13] added ChaiDesign image component used with icons/drawables --- chai/src/main/java/com/droidconke/chai/components/CText.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/chai/src/main/java/com/droidconke/chai/components/CText.kt b/chai/src/main/java/com/droidconke/chai/components/CText.kt index 5b4f713..b9d990b 100644 --- a/chai/src/main/java/com/droidconke/chai/components/CText.kt +++ b/chai/src/main/java/com/droidconke/chai/components/CText.kt @@ -85,6 +85,7 @@ internal fun AnimatedChaiText(modifier: Modifier=Modifier, * */ @Composable +//directly calls another composable thus we need to tell compiler to skip this during recomposition @NonRestartableComposable fun ChaiParagraph(modifier: Modifier=Modifier, text:String, From 04b6d7bca39626e1ac452398a735fa491a86835e Mon Sep 17 00:00:00 2001 From: GibsonRuitiari Date: Fri, 16 Sep 2022 19:17:30 +0300 Subject: [PATCH 09/13] added ChaiDesign image component used with icons/drawables --- chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt | 1 - .../src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt b/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt index bef45d2..124cf03 100644 --- a/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt +++ b/chaidemo/src/main/java/com/droidconke/chaidemo/ChaiDemo.kt @@ -23,7 +23,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.droidconke.chai.ChaiDCKE22Theme import com.droidconke.chai.atoms.ChaiColor -import com.droidconke.chai.atoms.ChaiWhite import com.droidconke.chai.components.* import com.droidconke.chai.utils.BreathingSpace13 import com.droidconke.chai.utils.BreathingSpace26 diff --git a/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt b/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt index 4225d77..82dc05f 100644 --- a/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt +++ b/chaidemo/src/main/java/com/droidconke/chaidemo/screens/TextDemo.kt @@ -45,7 +45,7 @@ fun TextScreen() { Column( Modifier .fillMaxSize() - .background(color = ChaiWhite) + .background(color = ChaiColor.ChaiWhite.value) .padding(horizontal = 13.dp, vertical = 5.dp) ) { BreathingSpace26() From 12fcd2fffebf991dca7be97a94f0c1a741a34a8a Mon Sep 17 00:00:00 2001 From: GibsonRuitiari Date: Fri, 16 Sep 2022 19:44:37 +0300 Subject: [PATCH 10/13] formatted added files using klint --- .../java/com/droidconke/chai/atoms/Color.kt | 60 +++++----- .../com/droidconke/chai/components/CText.kt | 104 ++++++++++-------- .../droidconke/chai/components/CTextStyle.kt | 103 ++++++++++------- .../chai/icons/{Icons.kt => ChaiIcon.kt} | 6 +- .../java/com/droidconke/chai/images/Images.kt | 32 +++--- .../com/droidconke/chai/modifier/clickable.kt | 33 +++--- .../droidconke/chai/utils/AnimateContent.kt | 17 +-- .../droidconke/chai/utils/animateAsState.kt | 24 ++-- .../java/com/droidconke/chai/utils/spec.kt | 8 +- 9 files changed, 225 insertions(+), 162 deletions(-) rename chai/src/main/java/com/droidconke/chai/icons/{Icons.kt => ChaiIcon.kt} (96%) diff --git a/chai/src/main/java/com/droidconke/chai/atoms/Color.kt b/chai/src/main/java/com/droidconke/chai/atoms/Color.kt index e49f756..ed72db0 100644 --- a/chai/src/main/java/com/droidconke/chai/atoms/Color.kt +++ b/chai/src/main/java/com/droidconke/chai/atoms/Color.kt @@ -62,15 +62,15 @@ val ChaiBlack = Color(0xFF000000) */ @Immutable // since we are using an internal constructor, values read from [ChaiColor] won't change after an instance is constructed @JvmInline -value class ChaiColor internal constructor(val value:Color){ +value class ChaiColor internal constructor(val value: Color) { /** * Changes the alpha of the ChaiColor * @param alpha alpha in form float to be applied to current ChaiColor * @return an instance of ChaiColor with modified alpha value */ - fun changeAlpha(alpha:Float) = ChaiColor(value.copy(alpha=alpha)) + fun changeAlpha(alpha: Float) = ChaiColor(value.copy(alpha = alpha)) - companion object{ + companion object { // should not be used in real components but, // can be used as a base value for ChaiColor @Stable @@ -78,31 +78,31 @@ value class ChaiColor internal constructor(val value:Color){ /* these are the Primary colours from Chai's Design spec document*/ @Stable - val ChaiBlue = ChaiColor(value=Color(0xFF000CEB)) + val ChaiBlue = ChaiColor(value = Color(0xFF000CEB)) @Stable val ChaiWhite = ChaiColor(value = Color(0xFFFFFFFF)) /* these are the Secondary colours from Chai's Design spec document */ @Stable - val ChaiRed = ChaiColor(value=Color(0xFFFF6E4D)) + val ChaiRed = ChaiColor(value = Color(0xFFFF6E4D)) @Stable - val ChaiTeal = ChaiColor(value=Color(0xFF00e2c3)) + val ChaiTeal = ChaiColor(value = Color(0xFF00e2c3)) @Stable - val ChaiFadedLime = ChaiColor(value=Color(0xFF7de1c3)) + val ChaiFadedLime = ChaiColor(value = Color(0xFF7de1c3)) /* these are the Neutrals from the Chai's Design spec document */ @Stable - val ChaiLightGrey = ChaiColor(value=Color(0xFFF5F5F5)) + val ChaiLightGrey = ChaiColor(value = Color(0xFFF5F5F5)) @Stable - val ChaiGrey = ChaiColor(value=Color(0xFFB1B1B1)) + val ChaiGrey = ChaiColor(value = Color(0xFFB1B1B1)) @Stable - val ChaiDarkGrey = ChaiColor(value=Color(0xFF5A5A5A)) + val ChaiDarkGrey = ChaiColor(value = Color(0xFF5A5A5A)) @Stable - val ChaiDarkerGrey =ChaiColor(value= Color(0xFF191d1d)) + val ChaiDarkerGrey = ChaiColor(value = Color(0xFF191d1d)) @Stable - val ChaiCoal = ChaiColor(value=Color(0xFF20201E)) + val ChaiCoal = ChaiColor(value = Color(0xFF20201E)) @Stable - val ChaiBlack = ChaiColor(value=Color(0xFF000000)) + val ChaiBlack = ChaiColor(value = Color(0xFF000000)) /** * Typically colors are 3 dimensional planes i.e x,y,z @@ -114,8 +114,13 @@ value class ChaiColor internal constructor(val value:Color){ * for comprehensive explanation see [full_explanation] (https://en.wikipedia.org/wiki/Color_space) * note: adapted from aosp */ - private fun multiplyColumn(column:Int,x:Float,y:Float, - z:Float,matrix:FloatArray) = x*matrix[column]+y*matrix[3+column]+z*matrix[6+column] + private fun multiplyColumn( + column: Int, + x: Float, + y: Float, + z: Float, + matrix: FloatArray + ) = x * matrix[column] + y * matrix[3 + column] + z * matrix[6 + column] private val M1 = floatArrayOf( 0.80405736f, 0.026893456f, @@ -152,7 +157,6 @@ value class ChaiColor internal constructor(val value:Color){ val y = colorXyz.green val z = colorXyz.blue - val l = multiplyColumn( column = 0, x = x, @@ -250,7 +254,7 @@ value class ChaiColor internal constructor(val value:Color){ ) } } - operator fun getValue(thisRef:Any?,property:KProperty<*>) = value + operator fun getValue(thisRef: Any?, property: KProperty<*>) = value } /** @@ -262,10 +266,12 @@ value class ChaiColor internal constructor(val value:Color){ * @receiver animation spec to be used, ideally should be an instance of [TweenSpec] * @return a new instance of animation spec whose duration is divided by 2 */ -private fun AnimationSpec.toColorSpec():AnimationSpec{ +private fun AnimationSpec.toColorSpec(): AnimationSpec { val tweenSpec = this as TweenSpec ?: return this - return tween(durationMillis = tweenSpec.durationMillis/2, - delayMillis = tweenSpec.delay,easing=tweenSpec.easing) + return tween( + durationMillis = tweenSpec.durationMillis / 2, + delayMillis = tweenSpec.delay, easing = tweenSpec.easing + ) } /** * Animates [ChaiColor] changes from one color to the other @@ -274,15 +280,19 @@ private fun AnimationSpec.toColorSpec():AnimationSpec{ * @return state object of type [ChaiColor] */ @Composable -internal fun animateChaiColorAsState(targetValue:ChaiColor,animationSpec: AnimationSpec = chaiAnimationSpec() -):State{ +internal fun animateChaiColorAsState( + targetValue: ChaiColor, + animationSpec: AnimationSpec = chaiAnimationSpec() +): State { val converter = remember(key1 = targetValue.value.colorSpace) { (ChaiColor.VectorConverter)(targetValue.value.colorSpace) } - return animateValueAsState(targetValue = targetValue, - typeConverter =converter, + return animateValueAsState( + targetValue = targetValue, + typeConverter = converter, animationSpec = animationSpec.toColorSpec(), - finishedListener = null) + finishedListener = null + ) } /** * TOBE Replaced diff --git a/chai/src/main/java/com/droidconke/chai/components/CText.kt b/chai/src/main/java/com/droidconke/chai/components/CText.kt index b9d990b..a8bf384 100644 --- a/chai/src/main/java/com/droidconke/chai/components/CText.kt +++ b/chai/src/main/java/com/droidconke/chai/components/CText.kt @@ -36,8 +36,6 @@ import com.droidconke.chai.utils.AnimateContentChange * * */ - - /** * Basic Text Construct, that adheres to the app's design system, * which is to be used by clients whenever they need @@ -48,14 +46,21 @@ import com.droidconke.chai.utils.AnimateContentChange * @param singleLine whether this text is a single line */ @Composable -internal fun ChaiText(modifier: Modifier=Modifier,text:String, -style: ChaiTextStyle,singleLine:Boolean=true){ +internal fun ChaiText( + modifier: Modifier = Modifier, + text: String, + style: ChaiTextStyle, + singleLine: Boolean = true +) { val styleAnimationState by animateChaiTextStyleAsState(targetValue = style) - Text(text = text, style = styleAnimationState.asComposedStyle(), - modifier = modifier, maxLines = when(singleLine){ - true->1 - else->Int.MAX_VALUE - }) + Text( + text = text, style = styleAnimationState.asComposedStyle(), + modifier = modifier, + maxLines = when (singleLine) { + true -> 1 + else -> Int.MAX_VALUE + } + ) } /** * Basic Text Construct that construct an animated text, and adheres to the app's design system, @@ -66,51 +71,60 @@ style: ChaiTextStyle,singleLine:Boolean=true){ * @param singleLine whether this text is a single line */ @Composable -internal fun AnimatedChaiText(modifier: Modifier=Modifier, - text: String, - style: ChaiTextStyle, - singleLine: Boolean=true){ +internal fun AnimatedChaiText( + modifier: Modifier = Modifier, + text: String, + style: ChaiTextStyle, + singleLine: Boolean = true +) { val styleAnimationState by animateChaiTextStyleAsState(targetValue = style) - AnimateContentChange(targetState = text, modifier = modifier) {animatedText-> - Text(text = animatedText, style = styleAnimationState.asComposedStyle(),maxLines = when(singleLine){ - true->1 - else->Int.MAX_VALUE - }) + AnimateContentChange(targetState = text, modifier = modifier) { animatedText -> + Text( + text = animatedText, style = styleAnimationState.asComposedStyle(), + maxLines = when (singleLine) { + true -> 1 + else -> Int.MAX_VALUE + } + ) } } - /** * Title based fonts * */ @Composable -//directly calls another composable thus we need to tell compiler to skip this during recomposition +// directly calls another composable thus we need to tell compiler to skip this during recomposition @NonRestartableComposable -fun ChaiParagraph(modifier: Modifier=Modifier, - text:String, - color: ChaiColor = ChaiColor.ChaiBlack)= ChaiText( - modifier=modifier, +fun ChaiParagraph( + modifier: Modifier = Modifier, + text: String, + color: ChaiColor = ChaiColor.ChaiBlack +) = ChaiText( + modifier = modifier, text = text, - style = ChaiTextStyle.CParagraphStyle.change(color=color) + style = ChaiTextStyle.CParagraphStyle.change(color = color) ) @Composable @NonRestartableComposable -fun ChaiPageTitle(modifier:Modifier=Modifier, - text: String, - color: ChaiColor = ChaiColor.ChaiCoal) = AnimatedChaiText( +fun ChaiPageTitle( + modifier: Modifier = Modifier, + text: String, + color: ChaiColor = ChaiColor.ChaiCoal +) = AnimatedChaiText( text = text, - modifier=modifier, - style = ChaiTextStyle.CPageTitleStyle.change(color=color)) + modifier = modifier, + style = ChaiTextStyle.CPageTitleStyle.change(color = color) +) @Composable @NonRestartableComposable -fun ChaiSubtitle(modifier: Modifier=Modifier,text: String,color: ChaiColor= ChaiColor.ChaiBlack) = - ChaiText(text = text, modifier = modifier, style= ChaiTextStyle.CSubtitleStyle.change(color=color) ) +fun ChaiSubtitle(modifier: Modifier = Modifier, text: String, color: ChaiColor = ChaiColor.ChaiBlack) = + ChaiText(text = text, modifier = modifier, style = ChaiTextStyle.CSubtitleStyle.change(color = color)) -//@Composable -//fun CParagraph(dParagraph: String) { +// @Composable +// fun CParagraph(dParagraph: String) { // Text( // text = dParagraph, // style = TextStyle( @@ -121,10 +135,10 @@ fun ChaiSubtitle(modifier: Modifier=Modifier,text: String,color: ChaiColor= Chai // ), // modifier = Modifier.fillMaxWidth() // ) -//} +// } // -//@Composable -//fun CPageTitle(pageTitle: String) { +// @Composable +// fun CPageTitle(pageTitle: String) { // Text( // text = pageTitle, // style = TextStyle( @@ -136,10 +150,10 @@ fun ChaiSubtitle(modifier: Modifier=Modifier,text: String,color: ChaiColor= Chai // ), // modifier = Modifier.fillMaxWidth() // ) -//} +// } // -//@Composable -//fun CSubtitle(dSubtitle: String) { +// @Composable +// fun CSubtitle(dSubtitle: String) { // Text( // text = dSubtitle, // style = TextStyle( @@ -151,10 +165,10 @@ fun ChaiSubtitle(modifier: Modifier=Modifier,text: String,color: ChaiColor= Chai // ), // modifier = Modifier.fillMaxWidth() // ) -//} +// } // -//@Composable -//fun CActionText(cAction: String) { +// @Composable +// fun CActionText(cAction: String) { // Text( // text = cAction, // style = TextStyle( @@ -166,6 +180,4 @@ fun ChaiSubtitle(modifier: Modifier=Modifier,text: String,color: ChaiColor= Chai // ), // modifier = Modifier.fillMaxWidth() // ) -//} - - +// } \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt b/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt index 92105bc..9b0c4bd 100644 --- a/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt +++ b/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt @@ -26,29 +26,33 @@ import com.droidconke.chai.utils.chaiAnimationSpec * This is the text style to be used by the client/across * the app instead of [TextStyle]. (Maybe implement a custom lint warning to enforce this?) * Example usage see ChaiDemo - * @param text color which is of type [ChaiColor] + * @param color which is of type [ChaiColor] * @param size text size * @param weight text weight * @param letterSpacing the spacing of letters * @param textAlign TextAlignment by default is [TextAlign.Center] */ @Immutable -class ChaiTextStyle internal constructor(val color: ChaiColor = ChaiColor.ChaiBlack, - val size: TextUnit, - val weight: FontWeight, - val letterSpacing: TextUnit = 0.sp, - val fontFamily: FontFamily, - val textAlign: TextAlign = TextAlign.Center){ +class ChaiTextStyle internal constructor( + val color: ChaiColor = ChaiColor.ChaiBlack, + val size: TextUnit, + val weight: FontWeight, + val letterSpacing: TextUnit = 0.sp, + val fontFamily: FontFamily, + val textAlign: TextAlign = TextAlign.Center +) { /** * Converts an instance of [ChaiTextStyle] into compose [TextStyle] * @return text style */ @Stable - internal fun asComposedStyle() = TextStyle(color=color.value, + internal fun asComposedStyle() = TextStyle( + color = color.value, fontSize = size, fontWeight = weight, fontFamily = fontFamily, - letterSpacing = letterSpacing, textAlign = textAlign) + letterSpacing = letterSpacing, textAlign = textAlign + ) - companion object{ + companion object { // annotating the variables with @Stable because it is a much stronger contract than val // note: compose compiler takes val to be unstable @Stable @@ -56,20 +60,27 @@ class ChaiTextStyle internal constructor(val color: ChaiColor = ChaiColor.ChaiBl @Stable private val montserratThin = FontFamily(Font(R.font.montserrat_thin)) @Stable - val CActionStyle = ChaiTextStyle(color = ChaiColor.ChaiRed, size = 10.sp, - weight = FontWeight.W700, fontFamily = montserratRegular) + val CActionStyle = ChaiTextStyle( + color = ChaiColor.ChaiRed, size = 10.sp, + weight = FontWeight.W700, fontFamily = montserratRegular + ) @Stable - val CSubtitleStyle = ChaiTextStyle(color= ChaiColor.ChaiRed,size=15.sp, - fontFamily = montserratRegular, weight = FontWeight.W700) + val CSubtitleStyle = ChaiTextStyle( + color = ChaiColor.ChaiRed, size = 15.sp, + fontFamily = montserratRegular, weight = FontWeight.W700 + ) @Stable - val CParagraphStyle = ChaiTextStyle(color= ChaiColor.ChaiBlack, - size=12.sp, - fontFamily = montserratRegular, weight = FontWeight.W500) + val CParagraphStyle = ChaiTextStyle( + color = ChaiColor.ChaiBlack, + size = 12.sp, + fontFamily = montserratRegular, weight = FontWeight.W500 + ) @Stable - val CPageTitleStyle = ChaiTextStyle(color= ChaiColor.ChaiBlue, - size=33.sp, - fontFamily = montserratThin, weight = FontWeight.W300) - + val CPageTitleStyle = ChaiTextStyle( + color = ChaiColor.ChaiBlue, + size = 33.sp, + fontFamily = montserratThin, weight = FontWeight.W300 + ) } /** @@ -82,20 +93,23 @@ class ChaiTextStyle internal constructor(val color: ChaiColor = ChaiColor.ChaiBl * @return an instance of ChaiTextStyle */ @Stable - internal fun change(color: ChaiColor =this.color, - weight: FontWeight =this.weight, - textAlign: TextAlign =this.textAlign, - fontFamily: FontFamily =this.fontFamily) = ChaiTextStyle(color=color, + internal fun change( + color: ChaiColor = this.color, + weight: FontWeight = this.weight, + textAlign: TextAlign = this.textAlign, + fontFamily: FontFamily = this.fontFamily + ) = ChaiTextStyle( + color = color, weight = weight, letterSpacing = letterSpacing, fontFamily = fontFamily, - size = size, textAlign = textAlign) - + size = size, textAlign = textAlign + ) } @OptIn(ExperimentalUnitApi::class) @Stable -private fun Float.toSp() = TextUnit(value=this, type = TextUnitType.Sp) +private fun Float.toSp() = TextUnit(value = this, type = TextUnitType.Sp) /** * A [ChaiTextStyle] properties animator * Currently it animates only the [ChaiTextStyle.color] & [ChaiTextStyle.size] properties @@ -105,21 +119,28 @@ private fun Float.toSp() = TextUnit(value=this, type = TextUnitType.Sp) */ @Suppress("UNCHECKED_CAST") @Composable -internal fun animateChaiTextStyleAsState(targetValue:ChaiTextStyle, - animationSpec: AnimationSpec = chaiAnimationSpec() +internal fun animateChaiTextStyleAsState( + targetValue: ChaiTextStyle, + animationSpec: AnimationSpec = chaiAnimationSpec() ): State { - val targetColorAnimationState = animateChaiColorAsState(targetValue = targetValue.color, - animationSpec = animationSpec as AnimationSpec + val targetColorAnimationState = animateChaiColorAsState( + targetValue = targetValue.color, + animationSpec = animationSpec as AnimationSpec ) - val targetSizeAnimationState = animateFloatAsState(targetValue = targetValue.size.value, - animationSpec= animationSpec as AnimationSpec + val targetSizeAnimationState = animateFloatAsState( + targetValue = targetValue.size.value, + animationSpec = animationSpec as AnimationSpec ) - return animateChaiAsState(initialValue = targetValue, - animationStates = listOf(targetColorAnimationState,targetSizeAnimationState), - targetBuilder = {animatedValues -> - val (color,size) = animatedValues - ChaiTextStyle(color= color as ChaiColor, size = (size as Float).toSp(), + return animateChaiAsState( + initialValue = targetValue, + animationStates = listOf(targetColorAnimationState, targetSizeAnimationState), + targetBuilder = { animatedValues -> + val (color, size) = animatedValues + ChaiTextStyle( + color = color as ChaiColor, size = (size as Float).toSp(), weight = targetValue.weight, letterSpacing = targetValue.letterSpacing, textAlign = targetValue.textAlign, - fontFamily = targetValue.fontFamily) - }) + fontFamily = targetValue.fontFamily + ) + } + ) } \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/icons/Icons.kt b/chai/src/main/java/com/droidconke/chai/icons/ChaiIcon.kt similarity index 96% rename from chai/src/main/java/com/droidconke/chai/icons/Icons.kt rename to chai/src/main/java/com/droidconke/chai/icons/ChaiIcon.kt index 8ed6ac9..c40bfca 100644 --- a/chai/src/main/java/com/droidconke/chai/icons/Icons.kt +++ b/chai/src/main/java/com/droidconke/chai/icons/ChaiIcon.kt @@ -27,9 +27,9 @@ import com.droidconke.chai.R */ @Immutable @JvmInline -value class ChaiIcon private constructor(@DrawableRes val drawableId:Int){ - companion object{ - @Stable +value class ChaiIcon private constructor(@DrawableRes val drawableId: Int) { + companion object { + @Stable val About = ChaiIcon(drawableId = R.drawable.about_icon) @Stable val FeedIcon = ChaiIcon(drawableId = R.drawable.feed_icon) diff --git a/chai/src/main/java/com/droidconke/chai/images/Images.kt b/chai/src/main/java/com/droidconke/chai/images/Images.kt index d12d876..a97e838 100644 --- a/chai/src/main/java/com/droidconke/chai/images/Images.kt +++ b/chai/src/main/java/com/droidconke/chai/images/Images.kt @@ -16,7 +16,6 @@ package com.droidconke.chai.images import androidx.compose.foundation.Image -import androidx.compose.foundation.clickable import androidx.compose.runtime.Composable import androidx.compose.runtime.NonRestartableComposable import androidx.compose.ui.Modifier @@ -37,17 +36,24 @@ import com.droidconke.chai.modifier.chaiClickable */ @Composable @NonRestartableComposable -fun ChaiImage(modifier: Modifier=Modifier, - icon:ChaiIcon?, - tint:ChaiColor?=null, - contentDescription:String?=null, - rippleEnabled:Boolean=true,onClick:(()->Unit)?=null){ - if (icon==null) return - Image(modifier = modifier.chaiClickable(rippleEnabled=rippleEnabled, - onClick = onClick), - painter =painterResource(id = icon.drawableId), - contentDescription =contentDescription, - colorFilter = tint.toColorFilter()) +fun ChaiImage( + modifier: Modifier = Modifier, + icon: ChaiIcon?, + tint: ChaiColor? = null, + contentDescription: String? = null, + rippleEnabled: Boolean = true, + onClick: (() -> Unit)? = null +) { + if (icon == null) return + Image( + modifier = modifier.chaiClickable( + rippleEnabled = rippleEnabled, + onClick = onClick + ), + painter = painterResource(id = icon.drawableId), + contentDescription = contentDescription, + colorFilter = tint.toColorFilter() + ) } -private fun ChaiColor?.toColorFilter() = this?.run { ColorFilter.tint(color=value) } \ No newline at end of file +private fun ChaiColor?.toColorFilter() = this?.run { ColorFilter.tint(color = value) } \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt b/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt index 6a5a1de..ab0e29c 100644 --- a/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt +++ b/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt @@ -1,7 +1,6 @@ package com.droidconke.chai.modifier import androidx.compose.foundation.clickable -import androidx.compose.foundation.indication import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.material.ripple.rememberRipple import androidx.compose.runtime.Stable @@ -10,7 +9,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.composed import com.droidconke.chai.atoms.ChaiColor - /** * Modifier that can be used to make components clickable * @param onClick the listener to be used when component is clicked @@ -21,17 +19,20 @@ import com.droidconke.chai.atoms.ChaiColor */ @Stable internal fun Modifier.chaiClickable( - rippleEnabled:Boolean=true, - rippleColor:ChaiColor?=null, - onClick: (()->Unit)?) = when(onClick!=null){ - true->composed { - clickable(onClick = onClick, - indication = rememberRipple( - color = rippleColor?.value ?: ChaiColor.Unspecified.value, - ).takeIf { - rippleEnabled - }, - interactionSource = remember { MutableInteractionSource() }) - } - else->this - } \ No newline at end of file + rippleEnabled: Boolean = true, + rippleColor: ChaiColor? = null, + onClick: (() -> Unit)? +) = when (onClick != null) { + true -> composed { + clickable( + onClick = onClick, + indication = rememberRipple( + color = rippleColor?.value ?: ChaiColor.Unspecified.value, + ).takeIf { + rippleEnabled + }, + interactionSource = remember { MutableInteractionSource() } + ) + } + else -> this +} \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt b/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt index c473d76..896e848 100644 --- a/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt +++ b/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt @@ -7,7 +7,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.IntSize - /** * Function which animates content change whenever state of a composable state *@param targetState composable's state to watch for changes @@ -17,11 +16,14 @@ import androidx.compose.ui.unit.IntSize @Suppress("UNCHECKED_CAST") @OptIn(ExperimentalAnimationApi::class) @Composable -internal fun AnimateContentChange(modifier:Modifier=Modifier, - targetState:T, animationSpec:AnimationSpec = chaiAnimationSpec(), - content:@Composable AnimatedVisibilityScope.(animatedTargetState:T)->Unit -){ - AnimatedContent(targetState = targetState, modifier = modifier,content=content, +internal fun AnimateContentChange( + modifier: Modifier = Modifier, + targetState: T, + animationSpec: AnimationSpec = chaiAnimationSpec(), + content: @Composable AnimatedVisibilityScope.(animatedTargetState: T) -> Unit +) { + AnimatedContent( + targetState = targetState, modifier = modifier, content = content, transitionSpec = { fadeIn( animationSpec = animationSpec as FiniteAnimationSpec, @@ -33,5 +35,6 @@ internal fun AnimateContentChange(modifier:Modifier=Modifier, animationSpec as FiniteAnimationSpec }, ) - }) + } + ) } \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt b/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt index bb2685d..07939ff 100644 --- a/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt +++ b/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt @@ -19,14 +19,22 @@ private fun State.toFlow() = snapshotFlow { this } * @return an animated state which is an instance ChaiDesign wrapped in [State] */ @Composable -internal inline fun animateChaiAsState(initialValue:T,animationStates:List>, - crossinline targetBuilder:(animatedValues:List)->T):State{ - val animationFlows:List> = animationStates.map(State<*>::toFlow) +internal inline fun animateChaiAsState( + initialValue: T, + animationStates: List>, + crossinline targetBuilder: (animatedValues: List) -> T +): State { + val animationFlows: List> = animationStates.map(State<*>::toFlow) // (combine scales linearly; find a better option probably)? - return combine(flows=animationFlows){_animationFlows-> - targetBuilder(_animationFlows.mapIndexed { index, flow -> (flow as State<*>).value ?: - throw NullPointerException("animation of the individual element at index $index of type " + - "is null hence cannot be animated")}) + return combine(flows = animationFlows) { _animationFlows -> + targetBuilder( + _animationFlows.mapIndexed { index, flow -> + (flow as State<*>).value + ?: throw NullPointerException( + "animation of the individual element at index $index of type " + + "is null hence cannot be animated" + ) + } + ) }.collectAsState(initial = initialValue) - } \ No newline at end of file diff --git a/chai/src/main/java/com/droidconke/chai/utils/spec.kt b/chai/src/main/java/com/droidconke/chai/utils/spec.kt index d078d2d..d8f6a76 100644 --- a/chai/src/main/java/com/droidconke/chai/utils/spec.kt +++ b/chai/src/main/java/com/droidconke/chai/utils/spec.kt @@ -7,11 +7,13 @@ import androidx.compose.runtime.Stable /** * Default duration time to be used in ChaiDesign system */ -const val ChaiDefaultAnimationMillis=250 +const val ChaiDefaultAnimationMillis = 250 /** * Basic/default animation spec to be used by ChaiDesign system * @return tween animation spec */ @Stable -internal fun chaiAnimationSpec() = tween(durationMillis= ChaiDefaultAnimationMillis, -easing = FastOutSlowInEasing) \ No newline at end of file +internal fun chaiAnimationSpec() = tween( + durationMillis = ChaiDefaultAnimationMillis, + easing = FastOutSlowInEasing +) \ No newline at end of file From b549de0740c0ae3317d039eb43d355deeb300af0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 16 Sep 2022 16:54:34 +0000 Subject: [PATCH 11/13] contrib-readme-action has updated readme --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index fc0176c..ca02347 100644 --- a/README.md +++ b/README.md @@ -196,13 +196,6 @@ We would endlessly like to thank the following contributors
Beatrice Kinya
- - - - GibsonRuitiari -
- 8BitsLives .❤️ -
From 54293be5fc5806b5e87094a4c79f791f598b404d Mon Sep 17 00:00:00 2001 From: GibsonRuitiari Date: Fri, 16 Sep 2022 20:03:36 +0300 Subject: [PATCH 12/13] added copyright added files --- .../com/droidconke/chai/components/CTextStyle.kt | 15 +++++++++++++++ .../com/droidconke/chai/modifier/clickable.kt | 15 +++++++++++++++ .../com/droidconke/chai/utils/AnimateContent.kt | 15 +++++++++++++++ .../com/droidconke/chai/utils/animateAsState.kt | 15 +++++++++++++++ .../main/java/com/droidconke/chai/utils/spec.kt | 15 +++++++++++++++ 5 files changed, 75 insertions(+) diff --git a/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt b/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt index 9b0c4bd..90db446 100644 --- a/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt +++ b/chai/src/main/java/com/droidconke/chai/components/CTextStyle.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2022 DroidconKE + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.droidconke.chai.components import androidx.compose.animation.core.AnimationSpec diff --git a/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt b/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt index ab0e29c..9ed941e 100644 --- a/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt +++ b/chai/src/main/java/com/droidconke/chai/modifier/clickable.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2022 DroidconKE + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.droidconke.chai.modifier import androidx.compose.foundation.clickable diff --git a/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt b/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt index 896e848..91cddf1 100644 --- a/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt +++ b/chai/src/main/java/com/droidconke/chai/utils/AnimateContent.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2022 DroidconKE + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.droidconke.chai.utils import androidx.compose.animation.* diff --git a/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt b/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt index 07939ff..dc7b981 100644 --- a/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt +++ b/chai/src/main/java/com/droidconke/chai/utils/animateAsState.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2022 DroidconKE + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.droidconke.chai.utils import androidx.compose.runtime.Composable diff --git a/chai/src/main/java/com/droidconke/chai/utils/spec.kt b/chai/src/main/java/com/droidconke/chai/utils/spec.kt index d8f6a76..53d3ede 100644 --- a/chai/src/main/java/com/droidconke/chai/utils/spec.kt +++ b/chai/src/main/java/com/droidconke/chai/utils/spec.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2022 DroidconKE + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.droidconke.chai.utils import androidx.compose.animation.core.FastOutSlowInEasing From 9717a5a4f4c8aa5716f6a2e665bf0db4068fd9a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 16 Sep 2022 17:03:56 +0000 Subject: [PATCH 13/13] contrib-readme-action has updated readme --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ca02347..922e968 100644 --- a/README.md +++ b/README.md @@ -141,17 +141,17 @@ We would endlessly like to thank the following contributors - - tamzi + + GibsonRuitiari
- Frank Tamre + 8BitsLives .❤️
- - GibsonRuitiari + + tamzi
- 8BitsLives .❤️ + Frank Tamre