Skip to content

Commit

Permalink
Component modules (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
npresseault authored Mar 21, 2024
1 parent 31a11ba commit 3d4731c
Show file tree
Hide file tree
Showing 49 changed files with 1,599 additions and 7 deletions.
1 change: 1 addition & 0 deletions build-logic/convention/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ tasks.withType<KotlinCompile>().configureEach {
dependencies {
compileOnly(libs.android.gradle.plugin)
compileOnly(libs.kotlin.gradle.plugin)
compileOnly(libs.kotlinx.binaryCompatibilityValidator)
}

gradlePlugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
with(target) {
with(pluginManager) {
apply("com.android.library")
apply("org.jlleitschuh.gradle.ktlint")
apply("org.jetbrains.kotlinx.binary-compatibility-validator")
apply("mirego.publish")
if (!plugins.hasPlugin("org.jetbrains.kotlin.multiplatform")) {
apply("org.jetbrains.kotlin.android")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.mirego.viewmodel.pilot

import kotlinx.validation.ApiValidationExtension
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure

internal fun Project.configureApiValidationPlugin() {
extensions.configure<ApiValidationExtension> {
nonPublicMarkers += listOf(
"com.mirego.pilot.components.InternalPilotComponentsApi"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ private fun Project.configureKotlin() {
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = Constants.JAVA_VERSION.toString()
freeCompilerArgs += listOf(
"-Xopt-in=kotlin.RequiresOptIn",
"-Xopt-in=com.mirego.pilot.components.InternalPilotComponentsApi"
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ class KotlinMultiplatformConventionPlugin : Plugin<Project> {
with(pluginManager) {
apply("com.android.library")
apply("org.jetbrains.kotlin.multiplatform")
apply("org.jlleitschuh.gradle.ktlint")
apply("org.jetbrains.kotlinx.binary-compatibility-validator")
apply("mirego.publish")
}

configureApiValidationPlugin()

extensions.configure<LibraryExtension> {
configureKotlinAndroid(this)
}
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {
alias(libs.plugins.android.library) apply false
alias(libs.plugins.ktlint) apply false
alias(libs.plugins.mirego.publish) apply false
alias(libs.plugins.kotlinx.binaryCompatibilityValidator) apply false
}

allprojects {
Expand Down
8 changes: 8 additions & 0 deletions components/android/coil/api/components-coil.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
public final class com/mirego/pilot/components/ui/coil/PilotRemoteImageKt {
public static final fun PilotRemoteImage-_kETKwk (Lcom/mirego/pilot/components/PilotRemoteImage;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;FLandroidx/compose/ui/graphics/ColorFilter;IZLandroidx/compose/runtime/Composer;II)V
}

public final class com/mirego/pilot/components/ui/coil/PilotResizableRemoteImageKt {
public static final fun PilotResizableRemoteImage-_kETKwk (Lcom/mirego/pilot/components/PilotResizableRemoteImage;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;FLandroidx/compose/ui/graphics/ColorFilter;IZLandroidx/compose/runtime/Composer;II)V
}

38 changes: 38 additions & 0 deletions components/android/coil/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@file:Suppress("DSL_SCOPE_VIOLATION")

plugins {
id("buildlogic.android.library")
}

group = "com.mirego.pilot"

android {
namespace = "com.mirego.pilot.components.material3"

buildFeatures {
compose = true
}

composeOptions {
kotlinCompilerExtensionVersion = libs.versions.androidx.compose.compiler.get()
}
}

dependencies {
implementation(projects.components)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.androidx.compose.foundation)
implementation(libs.androidx.compose.ui)
implementation(libs.coil.compose)
}

afterEvaluate {
publishing {
publications {
create<MavenPublication>("release") {
from(components["release"])
artifactId = "components-coil"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.mirego.pilot.components.ui.coil

import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.DefaultAlpha
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import coil.compose.AsyncImage
import coil.compose.AsyncImagePainter
import coil.request.ImageRequest
import com.mirego.pilot.components.PilotRemoteImage
import com.mirego.pilot.components.ui.pilotImageResourcePainter

@Composable
public fun PilotRemoteImage(
pilotRemoteImage: PilotRemoteImage,
modifier: Modifier = Modifier,
onState: ((AsyncImagePainter.State) -> Unit)? = null,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null,
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
allowHardware: Boolean = true,
) {
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(pilotRemoteImage.url)
.allowHardware(allowHardware)
.build(),
contentDescription = pilotRemoteImage.contentDescription,
modifier = modifier,
transform = pilotRemoteImage.placeholder
?.let { transformOf(pilotImageResourcePainter(it)) }
?: AsyncImagePainter.DefaultTransform,
onState = onState,
contentScale = contentScale,
alignment = alignment,
alpha = alpha,
colorFilter = colorFilter,
filterQuality = filterQuality,
)
}

@Stable
internal fun transformOf(placeholder: Painter): (AsyncImagePainter.State) -> AsyncImagePainter.State =
{ state ->
when (state) {
is AsyncImagePainter.State.Loading -> state.copy(painter = placeholder)
is AsyncImagePainter.State.Error -> state.copy(painter = placeholder)
else -> state
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.mirego.pilot.components.ui.coil

import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.DefaultAlpha
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import coil.compose.AsyncImage
import coil.compose.AsyncImagePainter
import coil.request.ImageRequest
import com.mirego.pilot.components.PilotResizableRemoteImage
import com.mirego.pilot.components.ui.pilotImageResourcePainter

@Composable
public fun PilotResizableRemoteImage(
pilotRemoteImage: PilotResizableRemoteImage,
modifier: Modifier = Modifier,
onState: ((AsyncImagePainter.State) -> Unit)? = null,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null,
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
allowHardware: Boolean = true,
) {
BoxWithConstraints(modifier) {
with(LocalDensity.current) {
val url = remember(pilotRemoteImage, maxWidth, maxHeight) {
val maxWidthPx = maxWidth.takeIf { it != Dp.Infinity && it != Dp.Unspecified }?.roundToPx()
val maxHeightPx = maxHeight.takeIf { it != Dp.Infinity && it != Dp.Unspecified }?.roundToPx()
if (maxWidthPx == null && maxHeightPx == null) return@remember null
pilotRemoteImage.url(maxWidthPx, maxHeightPx)
}
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(url)
.allowHardware(allowHardware)
.build(),
contentDescription = pilotRemoteImage.contentDescription,
modifier = modifier,
transform = pilotRemoteImage.placeholder
?.let { transformOf(pilotImageResourcePainter(it)) }
?: AsyncImagePainter.DefaultTransform,
onState = onState,
contentScale = contentScale,
alignment = alignment,
alpha = alpha,
colorFilter = colorFilter,
filterQuality = filterQuality,
)
}
}
}
12 changes: 12 additions & 0 deletions components/android/material3/api/components-material3.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
public final class com/mirego/pilot/components/ui/material3/PilotPickerKt {
public static final fun PilotPicker (Lcom/mirego/pilot/components/PilotPicker;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Modifier;ZLandroidx/compose/material3/MenuItemColors;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
}

public final class com/mirego/pilot/components/ui/material3/PilotRichTextKt {
public static final fun PilotRichText-IbK3jfQ (Lcom/mirego/pilot/components/PilotRichText;Landroidx/compose/ui/Modifier;JJLandroidx/compose/ui/text/font/FontStyle;Landroidx/compose/ui/text/font/FontWeight;Landroidx/compose/ui/text/font/FontFamily;JLandroidx/compose/ui/text/style/TextDecoration;Landroidx/compose/ui/text/style/TextAlign;JIZIILkotlin/jvm/functions/Function1;Landroidx/compose/ui/text/TextStyle;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;III)V
}

public final class com/mirego/pilot/components/ui/material3/PilotTextFieldKt {
public static final fun PilotTextField (Lcom/mirego/pilot/components/PilotTextField;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/ui/text/TextStyle;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;ZLandroidx/compose/foundation/text/KeyboardActions;ZIILandroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/material3/TextFieldColors;Landroidx/compose/runtime/Composer;III)V
}

41 changes: 41 additions & 0 deletions components/android/material3/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@file:Suppress("DSL_SCOPE_VIOLATION")

plugins {
id("buildlogic.android.library")
}

group = "com.mirego.pilot"

android {
namespace = "com.mirego.pilot.components.material3"

buildFeatures {
compose = true
}

composeOptions {
kotlinCompilerExtensionVersion = libs.versions.androidx.compose.compiler.get()
}
}

dependencies {
implementation(projects.components)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.lifecycle.viewmodel.ktx)
implementation(libs.androidx.compose.foundation)
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.lifecycle.common)
implementation(libs.androidx.compose.material3)
}

afterEvaluate {
publishing {
publications {
create<MavenPublication>("release") {
from(components["release"])
artifactId = "components-material3"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.mirego.pilot.components.ui.material3

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.MenuDefaults
import androidx.compose.material3.MenuItemColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
import com.mirego.pilot.components.PilotPicker

@Composable
public fun <LABEL : Any, ITEM : Any> PilotPicker(
pilotPicker: PilotPicker<LABEL, ITEM>,
modifier: Modifier = Modifier,
dropDownModifier: Modifier = Modifier,
dismissOnItemClick: Boolean = false,
colors: MenuItemColors = MenuDefaults.itemColors(),
itemColors: @Composable (label: LABEL) -> Unit,
item: @Composable (item: ITEM) -> Unit,
) {
var expanded by remember { mutableStateOf(false) }
Box {
Box(
modifier = modifier
.clickable(
onClick = { expanded = !expanded },
role = Role.Button,
),
) {
val labelValue by pilotPicker.label.collectAsState()
itemColors(labelValue)
}
// button unselected
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = dropDownModifier,
) {
val itemsValue by pilotPicker.items.collectAsState()
itemsValue.forEachIndexed { index, itemValue ->
DropdownMenuItem(
text = {
item(itemValue)
},
onClick = {
pilotPicker.onSelectedIndex(index)
if (dismissOnItemClick) {
expanded = false
}
},
colors = colors,
)
}
}
}
}
Loading

0 comments on commit 3d4731c

Please sign in to comment.