refactor: merge shared to composeApp

This commit is contained in:
2024-01-12 23:40:06 +08:00
parent d2bb28ef24
commit 8b330ff878
15 changed files with 9 additions and 8 deletions

View File

@@ -0,0 +1,78 @@
plugins {
autowire(libs.plugins.kotlin.multiplatform)
autowire(libs.plugins.android.library)
autowire(libs.plugins.jetbrains.compose)
}
kotlin {
androidTarget()
jvm("desktop")
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64(),
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = property.project.samples.composeApp.iosModuleName
isStatic = true
}
}
jvmToolchain(17)
sourceSets {
val commonMain by getting {
dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
api(projects.flexiuiCore)
api(com.highcapable.betterandroid.compose.multiplatform)
}
}
val androidMain by getting {
dependencies {
api(androidx.core.core.ktx)
api(androidx.appcompat.appcompat)
api(androidx.activity.activity)
api(androidx.activity.activity.compose)
api(com.highcapable.betterandroid.ui.component)
api(com.highcapable.betterandroid.ui.extension)
api(com.highcapable.betterandroid.system.extension)
}
}
val desktopMain by getting {
dependencies {
api(compose.desktop.currentOs)
}
}
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
}
}
android {
namespace = property.project.samples.composeApp.namespace
compileSdk = property.project.android.compileSdk
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
sourceSets["main"].res.srcDirs("src/androidMain/res")
sourceSets["main"].resources.srcDirs("src/commonMain/resources")
defaultConfig {
minSdk = property.project.android.minSdk
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

View File

@@ -0,0 +1,68 @@
/*
* Flexi UI - A flexible and useful UI component library.
* Copyright (C) 2019-2024 HighCapable
* https://github.com/BetterAndroid/FlexiUI
*
* Apache License Version 2.0
*
* 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
*
* https://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.
*
* This file is created by fankes on 2023/11/5.
*/
package com.highcapable.flexiui.demo
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import com.highcapable.betterandroid.compose.extension.ui.ComponentPadding
import com.highcapable.betterandroid.compose.multiplatform.systembar.PlatformSystemBarStyle
import com.highcapable.betterandroid.compose.multiplatform.systembar.rememberSystemBarsController
import com.highcapable.betterandroid.compose.multiplatform.systembar.setStyle
import com.highcapable.flexiui.FlexiTheme
import com.highcapable.flexiui.component.Surface
import com.highcapable.flexiui.demo.screen.LazyListScreen
import com.highcapable.flexiui.demo.screen.MainScreen
import com.highcapable.flexiui.demo.screen.SecondaryScreen
const val PROJECT_URL = "https://github.com/BetterAndroid/FlexiUI"
@Composable
private fun FlexiDemoTheme(content: @Composable () -> Unit) {
val systemBars = rememberSystemBarsController()
val darkMode by remember { Preferences.darkMode }
val followSystemDarkMode by remember { Preferences.followSystemDarkMode }
val currentDarkMode = if (followSystemDarkMode) isSystemInDarkTheme() else darkMode
val colorScheme by remember { Preferences.colorScheme }
systemBars.setStyle(
if (currentDarkMode)
PlatformSystemBarStyle.DarkTransparent
else PlatformSystemBarStyle.LightTransparent
)
FlexiTheme(
colors = colorScheme.toColors(currentDarkMode),
content = content
)
}
@Composable
fun App() {
FlexiDemoTheme {
// Surface will keep the content background color when animation.
Surface(padding = ComponentPadding()) {
Screen(Screen.Main) { MainScreen() }
Screen(Screen.Secondary) { SecondaryScreen() }
Screen(Screen.LazyList) { LazyListScreen() }
}
}
}

View File

@@ -0,0 +1,51 @@
/*
* Flexi UI - A flexible and useful UI component library.
* Copyright (C) 2019-2024 HighCapable
* https://github.com/BetterAndroid/FlexiUI
*
* Apache License Version 2.0
*
* 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
*
* https://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.
*
* This file is created by fankes on 2024/1/11.
*/
package com.highcapable.flexiui.demo
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.highcapable.flexiui.FlexiTheme
import com.highcapable.flexiui.component.Text
// TODO: Some components can be include to Flexi UI (To be determined)
@Composable
fun PrimarySpacer() {
Spacer(modifier = Modifier.size(10.dp))
}
@Composable
fun SecondarySpacer() {
Spacer(modifier = Modifier.size(5.dp))
}
@Composable
fun SecondaryText(text: String) {
Text(
text = text,
color = FlexiTheme.colors.textSecondary,
style = FlexiTheme.typography.secondary
)
}

View File

@@ -0,0 +1,146 @@
/*
* Flexi UI - A flexible and useful UI component library.
* Copyright (C) 2019-2024 HighCapable
* https://github.com/BetterAndroid/FlexiUI
*
* Apache License Version 2.0
*
* 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
*
* https://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.
*
* This file is created by fankes on 2024/1/11.
*/
package com.highcapable.flexiui.demo
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
import androidx.compose.runtime.mutableStateOf
import com.highcapable.flexiui.blueColors
import com.highcapable.flexiui.defaultColors
import com.highcapable.flexiui.greenColors
import com.highcapable.flexiui.isSystemColorAvailable
import com.highcapable.flexiui.orangeColors
import com.highcapable.flexiui.pinkColors
import com.highcapable.flexiui.purpleColors
import com.highcapable.flexiui.redColors
import com.highcapable.flexiui.systemColors
import com.highcapable.flexiui.yellowColors
@Stable
data class AppPreferences(
var colorScheme: MutableState<ColorScheme> = mutableStateOf(ColorScheme.Default),
var darkMode: MutableState<Boolean> = mutableStateOf(false),
var followSystemDarkMode: MutableState<Boolean> = mutableStateOf(false)
)
// TODO: Include ColorScheme to Flexi UI's Colors.kt
@Stable
val Preferences = AppPreferences()
@Stable
enum class ColorScheme {
Default,
DefaultBlack,
System,
SystemBlack,
Red,
RedBlack,
Pink,
PinkBlack,
Purple,
PurpleBlack,
Orange,
OrangeBlack,
Yellow,
YellowBlack,
Green,
GreenBlack,
Blue,
BlueBlack
}
@Composable
fun colorSchemes(): Array<ColorScheme> {
val defaultColors = arrayOf(
ColorScheme.Default,
ColorScheme.DefaultBlack
)
val systemColors = arrayOf(
ColorScheme.System,
ColorScheme.SystemBlack
)
val presetColors = arrayOf(
ColorScheme.Red,
ColorScheme.RedBlack,
ColorScheme.Pink,
ColorScheme.PinkBlack,
ColorScheme.Purple,
ColorScheme.PurpleBlack,
ColorScheme.Orange,
ColorScheme.OrangeBlack,
ColorScheme.Yellow,
ColorScheme.YellowBlack,
ColorScheme.Green,
ColorScheme.GreenBlack,
ColorScheme.Blue,
ColorScheme.BlueBlack
)
return if (isSystemColorAvailable())
defaultColors + systemColors + presetColors
else defaultColors + presetColors
}
@Composable
fun ColorScheme.toColors(darkMode: Boolean) = when (this) {
ColorScheme.Default -> defaultColors(darkMode)
ColorScheme.DefaultBlack -> defaultColors(darkMode, blackDarkMode = true)
ColorScheme.System -> systemColors(darkMode)
ColorScheme.SystemBlack -> systemColors(darkMode, blackDarkMode = true)
ColorScheme.Red -> redColors(darkMode)
ColorScheme.RedBlack -> redColors(darkMode, blackDarkMode = true)
ColorScheme.Pink -> pinkColors(darkMode)
ColorScheme.PinkBlack -> pinkColors(darkMode, blackDarkMode = true)
ColorScheme.Purple -> purpleColors(darkMode)
ColorScheme.PurpleBlack -> purpleColors(darkMode, blackDarkMode = true)
ColorScheme.Orange -> orangeColors(darkMode)
ColorScheme.OrangeBlack -> orangeColors(darkMode, blackDarkMode = true)
ColorScheme.Yellow -> yellowColors(darkMode)
ColorScheme.YellowBlack -> yellowColors(darkMode, blackDarkMode = true)
ColorScheme.Green -> greenColors(darkMode)
ColorScheme.GreenBlack -> greenColors(darkMode, blackDarkMode = true)
ColorScheme.Blue -> blueColors(darkMode)
ColorScheme.BlueBlack -> blueColors(darkMode, blackDarkMode = true)
}
@Stable
fun ColorScheme.toName() = when (this) {
ColorScheme.Default -> "Default"
ColorScheme.DefaultBlack -> "Default (Black)"
ColorScheme.System -> "System"
ColorScheme.SystemBlack -> "System (Black)"
ColorScheme.Red -> "Red"
ColorScheme.RedBlack -> "Red (Black)"
ColorScheme.Pink -> "Pink"
ColorScheme.PinkBlack -> "Pink (Black)"
ColorScheme.Purple -> "Purple"
ColorScheme.PurpleBlack -> "Purple (Black)"
ColorScheme.Orange -> "Orange"
ColorScheme.OrangeBlack -> "Orange (Black)"
ColorScheme.Yellow -> "Yellow"
ColorScheme.YellowBlack -> "Yellow (Black)"
ColorScheme.Green -> "Green"
ColorScheme.GreenBlack -> "Green (Black)"
ColorScheme.Blue -> "Blue"
ColorScheme.BlueBlack -> "Blue (Black)"
}

View File

@@ -0,0 +1,392 @@
/*
* Flexi UI - A flexible and useful UI component library.
* Copyright (C) 2019-2024 HighCapable
* https://github.com/BetterAndroid/FlexiUI
*
* Apache License Version 2.0
*
* 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
*
* https://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.
*
* This file is created by fankes on 2024/1/10.
*/
package com.highcapable.flexiui.demo
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp
import com.highcapable.betterandroid.compose.extension.ui.ImageVector
import com.highcapable.flexiui.resources.FlexiIcons
val FlexiIcons.GitHub by lazy {
ImageVector(
name = "github",
defaultWidth = 150.dp,
defaultHeight = 150.dp,
viewportWidth = 1024f,
viewportHeight = 1024f
) {
path(
fill = SolidColor(Color.White),
fillAlpha = 1.0f,
strokeAlpha = 1.0f,
strokeLineWidth = 1.0f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(512f, 12.6f)
curveToRelative(-282.8f, 0f, -512f, 229.2f, -512f, 512f)
curveToRelative(0f, 226.2f, 146.7f, 418.1f, 350.1f, 485.8f)
curveToRelative(25.6f, 4.7f, 35f, -11.1f, 35f, -24.6f)
curveToRelative(0f, -12.2f, -0.5f, -52.5f, -0.7f, -95.3f)
curveToRelative(-142.5f, 31f, -172.5f, -60.4f, -172.5f, -60.4f)
curveToRelative(-23.3f, -59.2f, -56.8f, -74.9f, -56.8f, -74.9f)
curveToRelative(-46.5f, -31.8f, 3.5f, -31.1f, 3.5f, -31.1f)
curveToRelative(51.4f, 3.6f, 78.5f, 52.8f, 78.5f, 52.8f)
curveToRelative(45.7f, 78.3f, 119.8f, 55.6f, 149f, 42.6f)
curveToRelative(4.6f, -33.1f, 17.9f, -55.7f, 32.5f, -68.5f)
curveToRelative(-113.7f, -12.9f, -233.3f, -56.9f, -233.3f, -253f)
curveToRelative(0f, -55.9f, 20f, -101.6f, 52.8f, -137.4f)
curveToRelative(-5.3f, -12.9f, -22.8f, -65f, 5f, -135.5f)
curveToRelative(0f, 0f, 43f, -13.8f, 140.8f, 52.5f)
curveToRelative(40.8f, -11.4f, 84.6f, -17f, 128.2f, -17.2f)
curveToRelative(43.5f, 0.2f, 87.3f, 5.9f, 128.3f, 17.2f)
curveToRelative(97.7f, -66.2f, 140.6f, -52.5f, 140.6f, -52.5f)
curveToRelative(27.9f, 70.5f, 10.3f, 122.6f, 5f, 135.5f)
curveToRelative(32.8f, 35.8f, 52.7f, 81.5f, 52.7f, 137.4f)
curveToRelative(0f, 196.6f, -119.8f, 239.9f, -233.8f, 252.6f)
curveToRelative(18.4f, 15.9f, 34.7f, 47f, 34.7f, 94.8f)
curveToRelative(0f, 68.5f, -0.6f, 123.6f, -0.6f, 140.5f)
curveToRelative(0f, 13.6f, 9.2f, 29.6f, 35.2f, 24.6f)
curveToRelative(203.3f, -67.8f, 349.9f, -259.6f, 349.9f, -485.8f)
curveToRelative(0f, -282.8f, -229.2f, -512f, -512f, -512f)
close()
}
}
}
val FlexiIcons.Home by lazy {
ImageVector(
name = "home",
defaultWidth = 50.dp,
defaultHeight = 50.dp,
viewportWidth = 1024f,
viewportHeight = 1024f
) {
path(
fill = SolidColor(Color.White),
fillAlpha = 1.0f,
strokeAlpha = 1.0f,
strokeLineWidth = 1.0f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(900.7f, 430.9f)
lineToRelative(-330.4f, -308f)
curveToRelative(-16.7f, -19f, -40.8f, -30f, -66.4f, -30f)
curveToRelative(-25.2f, 0f, -49.3f, 10.8f, -65.3f, 28.9f)
lineTo(120.5f, 430.8f)
curveToRelative(-15.9f, 16.3f, -20.5f, 39.8f, -11.7f, 60.8f)
curveToRelative(8.8f, 21f, 29.2f, 34.1f, 51.9f, 34.1f)
lineToRelative(28.7f, 0f)
lineToRelative(0f, 314.1f)
curveToRelative(0f, 48.7f, 39f, 88.3f, 87.7f, 88.3f)
lineToRelative(136.6f, 0f)
curveToRelative(17.7f, 0f, 33.5f, -14.3f, 33.5f, -32f)
lineTo(447.1f, 687f)
curveToRelative(0f, -8.9f, 5.8f, -16.8f, 14.7f, -16.8f)
lineToRelative(96.4f, 0f)
curveToRelative(8.9f, 0f, 15.7f, 8f, 15.7f, 16.8f)
lineToRelative(0f, 209f)
curveToRelative(0f, 17.8f, 14.8f, 32f, 32.5f, 32f)
lineToRelative(136.6f, 0f)
curveToRelative(48.7f, 0f, 88.6f, -39.5f, 88.6f, -88.3f)
lineToRelative(0f, -314.1f)
lineToRelative(28.5f, 0f)
curveToRelative(22.6f, 0f, 43f, -13.1f, 51.8f, -34f)
curveTo(921f, 470.8f, 916.5f, 447.2f, 900.7f, 430.9f)
lineTo(900.7f, 430.9f)
lineTo(900.7f, 430.9f)
moveTo(900.7f, 430.9f)
lineTo(900.7f, 430.9f)
close()
}
}
}
val FlexiIcons.Component by lazy {
ImageVector(
name = "component",
defaultWidth = 48.dp,
defaultHeight = 48.dp,
viewportWidth = 48f,
viewportHeight = 48f
) {
path(
fill = SolidColor(Color.White),
fillAlpha = 1.0f,
stroke = SolidColor(Color.White),
strokeAlpha = 1.0f,
strokeLineWidth = 4f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Round,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(18f, 6f)
horizontalLineTo(8f)
curveTo(6.895f, 6f, 6f, 6.895f, 6f, 8f)
verticalLineTo(18f)
curveTo(6f, 19.105f, 6.895f, 20f, 8f, 20f)
horizontalLineTo(18f)
curveTo(19.105f, 20f, 20f, 19.105f, 20f, 18f)
verticalLineTo(8f)
curveTo(20f, 6.895f, 19.105f, 6f, 18f, 6f)
close()
}
path(
fill = SolidColor(Color.White),
fillAlpha = 1.0f,
stroke = SolidColor(Color.White),
strokeAlpha = 1.0f,
strokeLineWidth = 4f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Round,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(18f, 28f)
horizontalLineTo(8f)
curveTo(6.895f, 28f, 6f, 28.895f, 6f, 30f)
verticalLineTo(40f)
curveTo(6f, 41.105f, 6.895f, 42f, 8f, 42f)
horizontalLineTo(18f)
curveTo(19.105f, 42f, 20f, 41.105f, 20f, 40f)
verticalLineTo(30f)
curveTo(20f, 28.895f, 19.105f, 28f, 18f, 28f)
close()
}
path(
fill = SolidColor(Color.White),
fillAlpha = 1.0f,
stroke = SolidColor(Color.White),
strokeAlpha = 1.0f,
strokeLineWidth = 4f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Round,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(35f, 20f)
curveTo(38.866f, 20f, 42f, 16.866f, 42f, 13f)
curveTo(42f, 9.134f, 38.866f, 6f, 35f, 6f)
curveTo(31.134f, 6f, 28f, 9.134f, 28f, 13f)
curveTo(28f, 16.866f, 31.134f, 20f, 35f, 20f)
close()
}
path(
fill = SolidColor(Color.White),
fillAlpha = 1.0f,
stroke = SolidColor(Color.White),
strokeAlpha = 1.0f,
strokeLineWidth = 4f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Round,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(40f, 28f)
horizontalLineTo(30f)
curveTo(28.895f, 28f, 28f, 28.895f, 28f, 30f)
verticalLineTo(40f)
curveTo(28f, 41.105f, 28.895f, 42f, 30f, 42f)
horizontalLineTo(40f)
curveTo(41.105f, 42f, 42f, 41.105f, 42f, 40f)
verticalLineTo(30f)
curveTo(42f, 28.895f, 41.105f, 28f, 40f, 28f)
close()
}
}
}
val FlexiIcons.ListAdd by lazy {
ImageVector(
name = "list_add",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f
) {
path(
fill = SolidColor(Color.White),
fillAlpha = 1.0f,
stroke = null,
strokeAlpha = 1.0f,
strokeLineWidth = 1.0f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(13f, 10f)
lineTo(3f, 10f)
curveToRelative(-0.55f, 0f, -1f, 0.45f, -1f, 1f)
reflectiveCurveToRelative(0.45f, 1f, 1f, 1f)
horizontalLineToRelative(10f)
curveToRelative(0.55f, 0f, 1f, -0.45f, 1f, -1f)
reflectiveCurveToRelative(-0.45f, -1f, -1f, -1f)
close()
moveTo(13f, 6f)
lineTo(3f, 6f)
curveToRelative(-0.55f, 0f, -1f, 0.45f, -1f, 1f)
reflectiveCurveToRelative(0.45f, 1f, 1f, 1f)
horizontalLineToRelative(10f)
curveToRelative(0.55f, 0f, 1f, -0.45f, 1f, -1f)
reflectiveCurveToRelative(-0.45f, -1f, -1f, -1f)
close()
moveTo(18f, 14f)
verticalLineToRelative(-3f)
curveToRelative(0f, -0.55f, -0.45f, -1f, -1f, -1f)
reflectiveCurveToRelative(-1f, 0.45f, -1f, 1f)
verticalLineToRelative(3f)
horizontalLineToRelative(-3f)
curveToRelative(-0.55f, 0f, -1f, 0.45f, -1f, 1f)
reflectiveCurveToRelative(0.45f, 1f, 1f, 1f)
horizontalLineToRelative(3f)
verticalLineToRelative(3f)
curveToRelative(0f, 0.55f, 0.45f, 1f, 1f, 1f)
reflectiveCurveToRelative(1f, -0.45f, 1f, -1f)
verticalLineToRelative(-3f)
horizontalLineToRelative(3f)
curveToRelative(0.55f, 0f, 1f, -0.45f, 1f, -1f)
reflectiveCurveToRelative(-0.45f, -1f, -1f, -1f)
horizontalLineToRelative(-3f)
close()
moveTo(3f, 16f)
horizontalLineToRelative(6f)
curveToRelative(0.55f, 0f, 1f, -0.45f, 1f, -1f)
reflectiveCurveToRelative(-0.45f, -1f, -1f, -1f)
lineTo(3f, 14f)
curveToRelative(-0.55f, 0f, -1f, 0.45f, -1f, 1f)
reflectiveCurveToRelative(0.45f, 1f, 1f, 1f)
close()
}
}
}
val FlexiIcons.Delete by lazy {
ImageVector(
name = "delete",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f
) {
path(
fill = SolidColor(Color.White),
fillAlpha = 1.0f,
strokeAlpha = 1.0f,
strokeLineWidth = 1.0f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(6f, 19f)
curveToRelative(0f, 1.1f, 0.9f, 2f, 2f, 2f)
horizontalLineToRelative(8f)
curveToRelative(1.1f, 0f, 2f, -0.9f, 2f, -2f)
verticalLineTo(9f)
curveToRelative(0f, -1.1f, -0.9f, -2f, -2f, -2f)
horizontalLineTo(8f)
curveToRelative(-1.1f, 0f, -2f, 0.9f, -2f, 2f)
verticalLineToRelative(10f)
close()
moveTo(18f, 4f)
horizontalLineToRelative(-2.5f)
lineToRelative(-0.71f, -0.71f)
curveToRelative(-0.18f, -0.18f, -0.44f, -0.29f, -0.7f, -0.29f)
horizontalLineTo(9.91f)
curveToRelative(-0.26f, 0f, -0.52f, 0.11f, -0.7f, 0.29f)
lineTo(8.5f, 4f)
horizontalLineTo(6f)
curveToRelative(-0.55f, 0f, -1f, 0.45f, -1f, 1f)
reflectiveCurveToRelative(0.45f, 1f, 1f, 1f)
horizontalLineToRelative(12f)
curveToRelative(0.55f, 0f, 1f, -0.45f, 1f, -1f)
reflectiveCurveToRelative(-0.45f, -1f, -1f, -1f)
close()
}
}
}
val FlexiIcons.DeleteForever by lazy {
ImageVector(
name = "delete_forever",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f
) {
path(
fill = SolidColor(Color.White),
fillAlpha = 1.0f,
stroke = null,
strokeAlpha = 1.0f,
strokeLineWidth = 1.0f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1.0f,
pathFillType = PathFillType.NonZero
) {
moveTo(6f, 19f)
curveToRelative(0f, 1.1f, 0.9f, 2f, 2f, 2f)
horizontalLineToRelative(8f)
curveToRelative(1.1f, 0f, 2f, -0.9f, 2f, -2f)
lineTo(18f, 7f)
lineTo(6f, 7f)
verticalLineToRelative(12f)
close()
moveTo(8.46f, 11.88f)
lineToRelative(1.41f, -1.41f)
lineTo(12f, 12.59f)
lineToRelative(2.12f, -2.12f)
lineToRelative(1.41f, 1.41f)
lineTo(13.41f, 14f)
lineToRelative(2.12f, 2.12f)
lineToRelative(-1.41f, 1.41f)
lineTo(12f, 15.41f)
lineToRelative(-2.12f, 2.12f)
lineToRelative(-1.41f, -1.41f)
lineTo(10.59f, 14f)
lineToRelative(-2.13f, -2.12f)
close()
moveTo(15.5f, 4f)
lineToRelative(-1f, -1f)
horizontalLineToRelative(-5f)
lineToRelative(-1f, 1f)
lineTo(5f, 4f)
verticalLineToRelative(2f)
horizontalLineToRelative(14f)
lineTo(19f, 4f)
close()
}
}
}

View File

@@ -0,0 +1,66 @@
/*
* Flexi UI - A flexible and useful UI component library.
* Copyright (C) 2019-2024 HighCapable
* https://github.com/BetterAndroid/FlexiUI
*
* Apache License Version 2.0
*
* 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
*
* https://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.
*
* This file is created by fankes on 2024/1/12.
*/
package com.highcapable.flexiui.demo
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
/** Simulate a router. */
@Stable
private var CurrentScreen = mutableStateOf(Screen.Main)
@Stable
enum class Screen {
Main,
Secondary,
LazyList
}
@Stable
class Router(private val screen: MutableState<Screen>) {
fun navigate(screen: Screen) {
this.screen.value = screen
}
fun goHome() = navigate(Screen.Main)
}
@Composable
fun rememberRouter() = Router(remember { CurrentScreen })
@Composable
fun Screen(screen: Screen, content: @Composable () -> Unit) {
val currentScreen by remember { CurrentScreen }
AnimatedVisibility(
visible = currentScreen == screen,
enter = fadeIn(),
exit = fadeOut()
) { content() }
}

View File

@@ -0,0 +1,102 @@
/*
* Flexi UI - A flexible and useful UI component library.
* Copyright (C) 2019-2024 HighCapable
* https://github.com/BetterAndroid/FlexiUI
*
* Apache License Version 2.0
*
* 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
*
* https://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.
*
* This file is created by fankes on 2024/1/12.
*/
@file:OptIn(ExperimentalFoundationApi::class)
package com.highcapable.flexiui.demo.screen
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.highcapable.betterandroid.compose.multiplatform.backpress.BackHandler
import com.highcapable.flexiui.component.Icon
import com.highcapable.flexiui.component.Scaffold
import com.highcapable.flexiui.component.SecondaryAppBar
import com.highcapable.flexiui.component.Tab
import com.highcapable.flexiui.component.TabRow
import com.highcapable.flexiui.component.Text
import com.highcapable.flexiui.demo.DeleteForever
import com.highcapable.flexiui.demo.ListAdd
import com.highcapable.flexiui.demo.rememberRouter
import com.highcapable.flexiui.resources.FlexiIcons
import kotlinx.coroutines.launch
@Composable
fun LazyListScreen() {
val router = rememberRouter()
val pageCount = 2
val state = rememberPagerState(pageCount = { pageCount })
val scope = rememberCoroutineScope()
Scaffold(
appBar = {
SecondaryAppBar(
title = { Text("Lazy List Demo") },
subtitle = { Text("0 items of list data", singleLine = true) },
navigationIcon = {
NavigationIconButton(onClick = { router.goHome() })
},
actions = {
ActionIconButton(onClick = { /* TODO */ }) {
Icon(FlexiIcons.ListAdd)
}
ActionIconButton(onClick = { /* TODO */ }) {
Icon(FlexiIcons.DeleteForever)
}
}
)
},
tab = {
TabRow(
selectedTabIndex = state.currentPage,
indicator = {
TabIndicator(modifier = Modifier.pagerTabIndicatorOffset(state))
}
) {
Tab(
selected = state.currentPage == 0,
onClick = { scope.launch { state.animateScrollToPage(0) } }
) { Text("Linear List") }
Tab(
selected = state.currentPage == 1,
onClick = { scope.launch { state.animateScrollToPage(1) } }
) { Text("Grid List") }
}
}
) {
HorizontalPager(
modifier = Modifier.fillMaxSize(),
state = state,
) { index ->
// TODO: To be implemented.
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) { Text("Page ${index + 1}. To be implemented.") }
}
BackHandler { router.goHome() }
}
}

View File

@@ -0,0 +1,227 @@
/*
* Flexi UI - A flexible and useful UI component library.
* Copyright (C) 2019-2024 HighCapable
* https://github.com/BetterAndroid/FlexiUI
*
* Apache License Version 2.0
*
* 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
*
* https://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.
*
* This file is created by fankes on 2024/1/12.
*/
@file:OptIn(ExperimentalFoundationApi::class)
package com.highcapable.flexiui.demo.screen
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.unit.dp
import com.highcapable.flexiui.component.AreaBox
import com.highcapable.flexiui.component.AreaColumn
import com.highcapable.flexiui.component.Button
import com.highcapable.flexiui.component.DropdownList
import com.highcapable.flexiui.component.DropdownMenuItem
import com.highcapable.flexiui.component.HorizontalItemBox
import com.highcapable.flexiui.component.Icon
import com.highcapable.flexiui.component.IconDefaults
import com.highcapable.flexiui.component.NavigationBarItem
import com.highcapable.flexiui.component.NavigationBarRow
import com.highcapable.flexiui.component.PrimaryAppBar
import com.highcapable.flexiui.component.Scaffold
import com.highcapable.flexiui.component.SwitchItem
import com.highcapable.flexiui.component.Text
import com.highcapable.flexiui.component.window.FlexiDialog
import com.highcapable.flexiui.demo.Component
import com.highcapable.flexiui.demo.GitHub
import com.highcapable.flexiui.demo.Home
import com.highcapable.flexiui.demo.PROJECT_URL
import com.highcapable.flexiui.demo.Preferences
import com.highcapable.flexiui.demo.PrimarySpacer
import com.highcapable.flexiui.demo.Screen
import com.highcapable.flexiui.demo.SecondarySpacer
import com.highcapable.flexiui.demo.SecondaryText
import com.highcapable.flexiui.demo.colorSchemes
import com.highcapable.flexiui.demo.rememberRouter
import com.highcapable.flexiui.demo.toName
import com.highcapable.flexiui.resources.FlexiIcons
import kotlinx.coroutines.launch
@Composable
fun MainScreen() {
val pageCount = 2
val state = rememberPagerState(pageCount = { pageCount })
val scope = rememberCoroutineScope()
val uriHandler = LocalUriHandler.current
Scaffold(
appBar = {
var showOpenUriDialog by remember { mutableStateOf(false) }
FlexiDialog(
visible = showOpenUriDialog,
onDismissRequest = { showOpenUriDialog = false },
title = { Text("Open Link") },
content = { Text("Open the project URL in the browser?") },
confirmButton = {
Button(
onClick = {
showOpenUriDialog = false
uriHandler.openUri(PROJECT_URL)
}
) { Text("Open") }
},
cancelButton = {
Button(
onClick = { showOpenUriDialog = false }
) { Text("Cancel") }
}
)
PrimaryAppBar(
title = { Text("Flexi UI Demo") },
actions = {
ActionIconButton(
onClick = { showOpenUriDialog = true }
) { Icon(FlexiIcons.GitHub) }
}
)
},
navigationBar = {
NavigationBarRow(
arrangement = Arrangement.SpaceAround
) {
NavigationBarItem(
selected = state.currentPage == 0,
onClick = { scope.launch { state.animateScrollToPage(page = 0) } },
icon = { Icon(FlexiIcons.Home, style = IconDefaults.style(size = 24.dp)) },
text = { Text("Home") }
)
NavigationBarItem(
selected = state.currentPage == 1,
onClick = { scope.launch { state.animateScrollToPage(page = 1) } },
icon = { Icon(FlexiIcons.Component, style = IconDefaults.style(size = 24.dp)) },
text = { Text("Component") }
)
}
}
) {
HorizontalPager(
modifier = Modifier.fillMaxSize(),
state = state,
) { index ->
when (index) {
0 -> MainHomePage()
1 -> MainComponentPage()
}
}
}
}
@Composable
fun MainHomePage() {
val scrollState = rememberScrollState()
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
AreaBox(modifier = Modifier.fillMaxWidth()) {
Text("Flexi UI is a flexible and useful UI component library.")
}
PrimarySpacer()
AreaColumn(modifier = Modifier.fillMaxWidth()) {
var colorScheme by remember { Preferences.colorScheme }
var darkMode by remember { Preferences.darkMode }
var followSystemDarkMode by remember { Preferences.followSystemDarkMode }
SecondaryText("Theme Style")
PrimarySpacer()
AnimatedVisibility(visible = !followSystemDarkMode) {
Column {
SwitchItem(
checked = darkMode,
onCheckedChange = { darkMode = it }
) { Text("Enable night mode") }
SecondarySpacer()
SecondaryText("Manually switch the current theme to night mode.")
PrimarySpacer()
}
}
SwitchItem(
checked = followSystemDarkMode,
onCheckedChange = { followSystemDarkMode = it }
) { Text("Follow system night mode") }
SecondarySpacer()
SecondaryText("Follow the system theme to switch day and night mode.")
PrimarySpacer()
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
var expanded by remember { mutableStateOf(false) }
Text("Current Theme")
PrimarySpacer()
DropdownList(
modifier = Modifier.fillMaxWidth(),
expanded = expanded,
onExpandedChange = { expanded = it },
text = { Text(colorScheme.toName()) },
) {
colorSchemes().forEach {
DropdownMenuItem(
actived = colorScheme == it,
onClick = {
expanded = false
colorScheme = it
}
) { Text(it.toName()) }
}
}
}
}
PrimarySpacer()
val router = rememberRouter()
HorizontalItemBox(
onClick = { router.navigate(Screen.Secondary) },
title = { Text("Single Page Demo") },
subtitle = { Text("Open a single page") }
)
PrimarySpacer()
HorizontalItemBox(
onClick = { router.navigate(Screen.LazyList) },
title = { Text("Lazy List Demo") },
subtitle = { Text("Open a lazy list page") }
)
PrimarySpacer()
}
}
@Composable
fun MainComponentPage() {
// TODO: To be implemented.
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) { Text("To be implemented.") }
}

View File

@@ -0,0 +1,67 @@
/*
* Flexi UI - A flexible and useful UI component library.
* Copyright (C) 2019-2024 HighCapable
* https://github.com/BetterAndroid/FlexiUI
*
* Apache License Version 2.0
*
* 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
*
* https://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.
*
* This file is created by fankes on 2024/1/12.
*/
package com.highcapable.flexiui.demo.screen
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.em
import com.highcapable.betterandroid.compose.multiplatform.backpress.BackHandler
import com.highcapable.flexiui.FlexiTheme
import com.highcapable.flexiui.component.AreaColumn
import com.highcapable.flexiui.component.Button
import com.highcapable.flexiui.component.Scaffold
import com.highcapable.flexiui.component.SecondaryAppBar
import com.highcapable.flexiui.component.Text
import com.highcapable.flexiui.demo.PrimarySpacer
import com.highcapable.flexiui.demo.rememberRouter
@Composable
fun SecondaryScreen() {
val router = rememberRouter()
Scaffold(
appBar = {
SecondaryAppBar(
title = { Text("Single Page Demo") },
navigationIcon = {
NavigationIconButton(onClick = { router.goHome() })
}
)
}
) {
AreaColumn(modifier = Modifier.fillMaxWidth()) {
Text(
"""
Now, you open a separate secondary page.
You can click the button below to back to the homepage.
""".trimIndent(),
style = FlexiTheme.typography.primary.copy(lineHeight = 2.em)
)
PrimarySpacer()
Button(
modifier = Modifier.fillMaxWidth(),
onClick = { router.goHome() }
) { Text("Take Me Home") }
}
BackHandler { router.goHome() }
}
}

View File

@@ -0,0 +1,27 @@
/*
* Flexi UI - A flexible and useful UI component library.
* Copyright (C) 2019-2024 HighCapable
* https://github.com/BetterAndroid/FlexiUI
*
* Apache License Version 2.0
*
* 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
*
* https://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.
*
* This file is created by fankes on 2023/11/5.
*/
@file:Suppress("unused")
import com.highcapable.betterandroid.compose.multiplatform.platform.AppComponentUIViewController
import com.highcapable.flexiui.demo.App
fun createMainViewController() = AppComponentUIViewController { App() }