diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..40a52f8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "bedrock"] + path = bedrock + url = git@labs.carlosmartino.dev:imcarlost/bedrock.git diff --git a/bedrock b/bedrock new file mode 160000 index 0000000..9080338 --- /dev/null +++ b/bedrock @@ -0,0 +1 @@ +Subproject commit 90803388008eea87d5a34f8dcac684e4c2eb0681 diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts deleted file mode 100644 index 87c84ba..0000000 --- a/core/common/build.gradle.kts +++ /dev/null @@ -1,46 +0,0 @@ -group = "dev.carlosmartino.core" - -plugins { - alias(libs.plugins.kotlinDevKit) - alias(libs.plugins.composeDevKit) -} - -kotlin { - sourceSets { - commonMain.dependencies { - api(libs.atomicfu) - api(libs.kotlinx.datetime) - api(libs.kotlinx.coroutines.core) - api(libs.kotlinx.serialization.json) - api(libs.koin.core) - api(libs.koin.compose) - api(libs.koin.compose.viewmodel) - api(libs.koin.compose.viewmodel.navigation) - - implementation(libs.androidx.security.crypto) - implementation(libs.androidx.datastore.preferences) - implementation(libs.androidx.datastore.preferences.core) - implementation(libs.multiplatform.settings.core) - implementation(libs.multiplatform.settings.noarg) - implementation(libs.multiplatform.settings.coroutines) - implementation(libs.multiplatform.settings.serialization) - implementation(libs.moko.permissions) - implementation(libs.moko.permissions.compose) - implementation(libs.moko.permissions.bluetooth) - implementation(libs.moko.permissions.camera) - implementation(libs.moko.permissions.contacts) - implementation(libs.moko.permissions.gallery) - implementation(libs.moko.permissions.location) - implementation(libs.moko.permissions.microphone) - implementation(libs.moko.permissions.motion) - implementation(libs.moko.permissions.notifications) - implementation(libs.moko.permissions.storage) - } - - androidMain.dependencies { - api(libs.kotlinx.coroutines.android) - api(libs.koin.android) - api(libs.multiplatform.settings.core) - } - } -} diff --git a/core/common/src/androidMain/kotlin/cl/homelogic/platform/common/Platform.android.kt b/core/common/src/androidMain/kotlin/cl/homelogic/platform/common/Platform.android.kt deleted file mode 100644 index bf87ba2..0000000 --- a/core/common/src/androidMain/kotlin/cl/homelogic/platform/common/Platform.android.kt +++ /dev/null @@ -1,6 +0,0 @@ -package cl.homelogic.platform.common - -@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") -actual object Platform { - actual fun getType() = PlatformTypes.Android -} diff --git a/core/common/src/androidMain/kotlin/cl/homelogic/platform/common/logging/Trace.android.kt b/core/common/src/androidMain/kotlin/cl/homelogic/platform/common/logging/Trace.android.kt deleted file mode 100644 index 5358804..0000000 --- a/core/common/src/androidMain/kotlin/cl/homelogic/platform/common/logging/Trace.android.kt +++ /dev/null @@ -1,18 +0,0 @@ -package cl.homelogic.platform.common.logging - -import android.util.Log - -internal actual fun logPlatform( - severity: Severity, - tag: String, - message: String, -) { - when (severity) { - Severity.Debug -> Log.d(tag, message) - Severity.Verbose -> Log.v(tag, message) - Severity.Info -> Log.i(tag, message) - Severity.Warn -> Log.w(tag, message) - Severity.Error -> Log.e(tag, message) - else -> {} - } -} diff --git a/core/common/src/androidMain/kotlin/cl/homelogic/platform/common/settings/SettingsSource.android.kt b/core/common/src/androidMain/kotlin/cl/homelogic/platform/common/settings/SettingsSource.android.kt deleted file mode 100644 index e08242f..0000000 --- a/core/common/src/androidMain/kotlin/cl/homelogic/platform/common/settings/SettingsSource.android.kt +++ /dev/null @@ -1,30 +0,0 @@ -package cl.homelogic.platform.common.settings - -import android.content.Context -import androidx.security.crypto.EncryptedSharedPreferences -import androidx.security.crypto.MasterKey -import com.russhwolf.settings.Settings -import com.russhwolf.settings.SharedPreferencesSettings - -class AndroidSettingsFactory( - private val context: Context, -) : ISettingsFactory { - override fun createSettings(name: String?): Settings { - val prefName = name ?: "secure_settings" - - val masterKey = MasterKey - .Builder(context) - .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) - .build() - - val sharedPreferences = EncryptedSharedPreferences.create( - context, - prefName, - masterKey, - EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, - EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM, - ) - - return SharedPreferencesSettings(sharedPreferences) - } -} diff --git a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/Platform.kt b/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/Platform.kt deleted file mode 100644 index dcd50ec..0000000 --- a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/Platform.kt +++ /dev/null @@ -1,11 +0,0 @@ -package cl.homelogic.platform.common - -enum class PlatformTypes { - IOS, - Android, -} - -@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") -expect object Platform { - fun getType(): PlatformTypes -} diff --git a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/logging/Trace.kt b/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/logging/Trace.kt deleted file mode 100644 index 476b096..0000000 --- a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/logging/Trace.kt +++ /dev/null @@ -1,230 +0,0 @@ -package cl.homelogic.platform.common.logging - -import kotlinx.atomicfu.locks.SynchronizedObject -import kotlinx.atomicfu.locks.synchronized -import kotlinx.datetime.TimeZone -import kotlinx.datetime.toLocalDateTime -import kotlin.time.Clock -import kotlin.time.ExperimentalTime -import kotlin.time.Instant - -enum class Severity { - Debug, - Verbose, - Info, - Warn, - Error, - None, -} - -enum class TreeRoots { - Navigation, - Koin, - AssetsParser, - DesignSystem, - Settings, -} - -private data class LogEntry( - val timestamp: Instant, - val severity: Severity, - val tag: String, - val message: String, -) - -private interface LogTree { - val maxEntries: Int - val logs: ArrayDeque - - fun log( - severity: Severity, - tag: String, - message: String, - ) - - fun getFormattedLogs(): String -} - -private class MemoryLogTree( - override val maxEntries: Int, -) : LogTree { - override val logs = ArrayDeque(maxEntries) - private val logsLock = SynchronizedObject() - - override fun log( - severity: Severity, - tag: String, - message: String, - ) { - synchronized(logsLock) { - if (logs.size >= maxEntries) { - logs.removeFirst() - } - logs.addLast(LogEntry(Clock.System.now(), severity, tag, message)) - } - } - - override fun getFormattedLogs(): String = - buildString { - synchronized(logsLock) { - logs.forEach { entry -> - appendLine( - "${entry.timestamp.toLocalDateTime(TimeZone.currentSystemDefault())} " + - "${entry.severity.name.padEnd(7)} " + - "${entry.tag}: ${entry.message}", - ) - } - } - } -} - -internal expect fun logPlatform( - severity: Severity, - tag: String, - message: String, -) - -class Trace { - companion object { - private const val DEFAULT_LOG_MESSAGE = "The message content was empty" - - private var _isDebug: Boolean = false - private var _minSeverity: Severity = Severity.None - private var _treeSize: Int = 20 - private val _trees = HashMap() - - fun initialize(isDebug: Boolean) { - _isDebug = isDebug - _minSeverity = if (_isDebug) Severity.Verbose else Severity.None - plantTree(TreeRoots.Navigation) - plantTree(TreeRoots.Koin) - plantTree(TreeRoots.AssetsParser) - plantTree(TreeRoots.DesignSystem) - plantTree(TreeRoots.Settings) - } - - fun setLoggingSeverity(severity: Severity) { - _minSeverity = severity - } - - fun setTreeSizes(size: Int) { - _treeSize = size - } - - private fun plantTree(name: TreeRoots) { - _trees[name.name] = MemoryLogTree(_treeSize) - } - - fun plantTree(name: String) { - _trees[name] = MemoryLogTree(_treeSize) - } - - fun getTreeContent(name: String): String = _trees[name]?.getFormattedLogs() ?: "Tree '$name' not found" - - private fun log( - severity: Severity, - tag: String, - message: String, - ) { - if (severity == Severity.None || severity.ordinal < _minSeverity.ordinal) return - logPlatform(severity, "Trace - $tag", message) - _trees.values.forEach { tree -> - tree.log(severity, tag, message) - } - } - - fun v( - tag: TreeRoots, - message: String, - ) { - v(tag.name, message) - } - - fun d( - tag: TreeRoots, - message: String, - ) { - d(tag.name, message) - } - - fun i( - tag: TreeRoots, - message: String, - ) { - i(tag.name, message) - } - - fun w( - tag: TreeRoots, - message: String, - ) { - w(tag.name, message) - } - - fun e( - tag: TreeRoots, - message: String, - ) { - e(tag.name, message) - } - - fun v( - tag: String, - message: String?, - ) { - log(Severity.Verbose, tag, message ?: DEFAULT_LOG_MESSAGE) - } - - fun d( - tag: String, - message: String?, - ) { - log(Severity.Debug, tag, message ?: DEFAULT_LOG_MESSAGE) - } - - fun i( - tag: String, - message: String?, - ) { - log(Severity.Info, tag, message ?: DEFAULT_LOG_MESSAGE) - } - - fun w( - tag: String, - message: String?, - ) { - log(Severity.Warn, tag, message ?: DEFAULT_LOG_MESSAGE) - } - - fun e( - tag: String, - message: String?, - ) { - log(Severity.Error, tag, message ?: DEFAULT_LOG_MESSAGE) - } - - fun e( - tag: String, - message: String, - throwable: Throwable, - ) { - log( - Severity.Error, - tag, - (message + "\n" + throwable.message + "\n" + throwable.stackTraceToString()), - ) - } - - fun e( - tag: String, - message: String, - exception: Exception, - ) { - log( - Severity.Error, - tag, - (message + "\n" + exception.message + "\n" + exception.stackTraceToString()), - ) - } - } -} diff --git a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/logging/TraceKoinLogger.kt b/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/logging/TraceKoinLogger.kt deleted file mode 100644 index caa35b1..0000000 --- a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/logging/TraceKoinLogger.kt +++ /dev/null @@ -1,24 +0,0 @@ -package cl.homelogic.platform.common.logging - -import org.koin.core.logger.Level -import org.koin.core.logger.Logger -import org.koin.core.logger.MESSAGE - -class TraceKoinLogger : Logger() { - override fun display( - level: Level, - msg: MESSAGE, - ) { - when (level) { - Level.DEBUG -> Trace.d(DEFAULT_TAG, msg) - Level.INFO -> Trace.i(DEFAULT_TAG, msg) - Level.WARNING -> Trace.w(DEFAULT_TAG, msg) - Level.ERROR -> Trace.e(DEFAULT_TAG, msg) - Level.NONE -> {} - } - } - - companion object { - const val DEFAULT_TAG = "Koin" - } -} diff --git a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/permissions/PermissionManager.kt b/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/permissions/PermissionManager.kt deleted file mode 100644 index 90c1f5a..0000000 --- a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/permissions/PermissionManager.kt +++ /dev/null @@ -1,77 +0,0 @@ -package cl.homelogic.platform.common.permissions - -import cl.homelogic.platform.common.permissions.PermissionStatus.Denied -import cl.homelogic.platform.common.permissions.PermissionStatus.Granted -import cl.homelogic.platform.common.permissions.PermissionStatus.NotGranted -import dev.icerock.moko.permissions.Permission -import dev.icerock.moko.permissions.PermissionState -import dev.icerock.moko.permissions.bluetooth.BluetoothAdvertisePermission -import dev.icerock.moko.permissions.bluetooth.BluetoothConnectPermission -import dev.icerock.moko.permissions.bluetooth.BluetoothLEPermission -import dev.icerock.moko.permissions.bluetooth.BluetoothScanPermission -import dev.icerock.moko.permissions.camera.CameraPermission -import dev.icerock.moko.permissions.contacts.ContactPermission -import dev.icerock.moko.permissions.gallery.GalleryPermission -import dev.icerock.moko.permissions.location.BackgroundLocationPermission -import dev.icerock.moko.permissions.location.CoarseLocationPermission -import dev.icerock.moko.permissions.location.LocationPermission -import dev.icerock.moko.permissions.microphone.RecordAudioPermission -import dev.icerock.moko.permissions.motion.MotionPermission -import dev.icerock.moko.permissions.notifications.RemoteNotificationPermission -import dev.icerock.moko.permissions.storage.StoragePermission -import dev.icerock.moko.permissions.storage.WriteStoragePermission - -enum class PermissionType { - CAMERA, - GALLERY, - STORAGE, - WRITE_STORAGE, - LOCATION, - COARSE_LOCATION, - BACKGROUND_LOCATION, - BLUETOOTH_LE, - REMOTE_NOTIFICATION, - RECORD_AUDIO, - BLUETOOTH_SCAN, - BLUETOOTH_ADVERTISE, - BLUETOOTH_CONNECT, - CONTACTS, - MOTION, - ; - - companion object { - fun PermissionType.toMokoPermission() = - when (this) { - CAMERA -> CameraPermission - GALLERY -> GalleryPermission - STORAGE -> StoragePermission - WRITE_STORAGE -> WriteStoragePermission - LOCATION -> LocationPermission - COARSE_LOCATION -> CoarseLocationPermission - BACKGROUND_LOCATION -> BackgroundLocationPermission - BLUETOOTH_LE -> BluetoothLEPermission - REMOTE_NOTIFICATION -> RemoteNotificationPermission - RECORD_AUDIO -> RecordAudioPermission - BLUETOOTH_SCAN -> BluetoothScanPermission - BLUETOOTH_ADVERTISE -> BluetoothAdvertisePermission - BLUETOOTH_CONNECT -> BluetoothConnectPermission - CONTACTS -> ContactPermission - MOTION -> MotionPermission - } - } -} - -fun PermissionState.toPermissionStatus() = - when (this) { - PermissionState.NotDetermined -> NotGranted - PermissionState.NotGranted -> NotGranted - PermissionState.Granted -> Granted - PermissionState.Denied -> Denied - PermissionState.DeniedAlways -> Denied - } - -enum class PermissionStatus { - NotGranted, - Granted, - Denied, -} diff --git a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/permissions/composables/PermissionSystem.kt b/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/permissions/composables/PermissionSystem.kt deleted file mode 100644 index 3d77d88..0000000 --- a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/permissions/composables/PermissionSystem.kt +++ /dev/null @@ -1,74 +0,0 @@ -package cl.homelogic.platform.common.permissions.composables - -import androidx.compose.foundation.layout.LayoutScopeMarker -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Immutable -import androidx.compose.runtime.remember -import cl.homelogic.platform.common.permissions.PermissionStatus -import cl.homelogic.platform.common.permissions.PermissionType -import cl.homelogic.platform.common.permissions.PermissionType.Companion.toMokoPermission -import cl.homelogic.platform.common.permissions.toPermissionStatus -import dev.icerock.moko.permissions.DeniedAlwaysException -import dev.icerock.moko.permissions.DeniedException -import dev.icerock.moko.permissions.PermissionsController -import dev.icerock.moko.permissions.RequestCanceledException -import dev.icerock.moko.permissions.compose.PermissionsControllerFactory -import dev.icerock.moko.permissions.compose.rememberPermissionsControllerFactory - -@Composable -fun PermissionSystem( - content: @Composable PermissionsScope.() -> Unit, -) { - val factory: PermissionsControllerFactory = rememberPermissionsControllerFactory() - val controller: PermissionsController = remember(factory) { - factory.createPermissionsController() - } - - PermissionsScopeInstance(controller).content() -} - -@LayoutScopeMarker -@Immutable -interface PermissionsScope { - suspend fun requestPermission(permission: PermissionType): PermissionStatus - - suspend fun isPermissionGranted(permission: PermissionType): Boolean - - suspend fun getPermissionState(permission: PermissionType): PermissionStatus - - fun openAppSettings() -} - -internal class PermissionsScopeInstance( - private val permissionsController: PermissionsController, -) : PermissionsScope { - override suspend fun requestPermission(permission: PermissionType): PermissionStatus { - try { - permissionsController.providePermission(permission.toMokoPermission()) - return PermissionStatus.Granted - } catch (deniedAlways: DeniedAlwaysException) { - return PermissionStatus.Denied - } catch (denied: DeniedException) { - return PermissionStatus.Denied - } catch (canceled: RequestCanceledException) { - return PermissionStatus.NotGranted - } catch (exception: Exception) { - return PermissionStatus.NotGranted - } - } - - override suspend fun isPermissionGranted(permission: PermissionType): Boolean = - permissionsController.isPermissionGranted( - permission.toMokoPermission(), - ) - - override suspend fun getPermissionState(permission: PermissionType): PermissionStatus = - permissionsController - .getPermissionState( - permission.toMokoPermission(), - ).toPermissionStatus() - - override fun openAppSettings() { - permissionsController.openAppSettings() - } -} diff --git a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/settings/SettingsSource.kt b/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/settings/SettingsSource.kt deleted file mode 100644 index 2387952..0000000 --- a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/settings/SettingsSource.kt +++ /dev/null @@ -1,57 +0,0 @@ -package cl.homelogic.platform.common.settings - -import cl.homelogic.platform.common.logging.Trace -import cl.homelogic.platform.common.logging.TreeRoots -import com.russhwolf.settings.Settings - -interface ISettingsSource { - fun get( - key: PreferenceKey, - defaultValue: T, - ): T - - fun set( - key: PreferenceKey, - value: T, - ) - - fun remove(key: PreferenceKey) - - fun clear() -} - -class SettingsSource( - private val settings: Settings, -) : ISettingsSource { - // TODO: add fuction to check if key exists - - override fun get( - key: PreferenceKey, - defaultValue: T, - ): T { - Trace.d(TreeRoots.Settings, "Retrieving setting: ${key.key}") - return key.getValue(settings, defaultValue) - } - - override fun set( - key: PreferenceKey, - value: T, - ) { - Trace.d(TreeRoots.Settings, "Storing setting: ${key.key} : $value") - key.setValue(settings, value) - } - - override fun remove(key: PreferenceKey) { - Trace.d(TreeRoots.Settings, "Removing setting: ${key.key}") - settings.remove(key.key) - } - - override fun clear() { - Trace.d(TreeRoots.Settings, "Deleting all settings") - settings.clear() - } -} - -interface ISettingsFactory { - fun createSettings(name: String? = null): Settings -} diff --git a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/settings/SettingsStructure.kt b/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/settings/SettingsStructure.kt deleted file mode 100644 index b20b0c3..0000000 --- a/core/common/src/commonMain/kotlin/cl/homelogic/platform/common/settings/SettingsStructure.kt +++ /dev/null @@ -1,101 +0,0 @@ -package cl.homelogic.platform.common.settings - -import com.russhwolf.settings.Settings - -sealed class PreferenceKey( - val key: String, -) { - abstract fun getValue( - settings: Settings, - defaultValue: T, - ): T - - abstract fun setValue( - settings: Settings, - value: T, - ) - - class StringKey( - key: String, - ) : PreferenceKey(key) { - override fun getValue( - settings: Settings, - defaultValue: String, - ): String = settings.getString(key, defaultValue) - - override fun setValue( - settings: Settings, - value: String, - ) = settings.putString(key, value) - } - - class IntKey( - key: String, - ) : PreferenceKey(key) { - override fun getValue( - settings: Settings, - defaultValue: Int, - ): Int = settings.getInt(key, defaultValue) - - override fun setValue( - settings: Settings, - value: Int, - ) = settings.putInt(key, value) - } - - class LongKey( - key: String, - ) : PreferenceKey(key) { - override fun getValue( - settings: Settings, - defaultValue: Long, - ): Long = settings.getLong(key, defaultValue) - - override fun setValue( - settings: Settings, - value: Long, - ) = settings.putLong(key, value) - } - - class FloatKey( - key: String, - ) : PreferenceKey(key) { - override fun getValue( - settings: Settings, - defaultValue: Float, - ): Float = settings.getFloat(key, defaultValue) - - override fun setValue( - settings: Settings, - value: Float, - ) = settings.putFloat(key, value) - } - - class DoubleKey( - key: String, - ) : PreferenceKey(key) { - override fun getValue( - settings: Settings, - defaultValue: Double, - ): Double = settings.getDouble(key, defaultValue) - - override fun setValue( - settings: Settings, - value: Double, - ) = settings.putDouble(key, value) - } - - class BooleanKey( - key: String, - ) : PreferenceKey(key) { - override fun getValue( - settings: Settings, - defaultValue: Boolean, - ): Boolean = settings.getBoolean(key, defaultValue) - - override fun setValue( - settings: Settings, - value: Boolean, - ) = settings.putBoolean(key, value) - } -} diff --git a/core/common/src/iosMain/kotlin/cl/homelogic/platform/common/Platform.ios.kt b/core/common/src/iosMain/kotlin/cl/homelogic/platform/common/Platform.ios.kt deleted file mode 100644 index db08433..0000000 --- a/core/common/src/iosMain/kotlin/cl/homelogic/platform/common/Platform.ios.kt +++ /dev/null @@ -1,6 +0,0 @@ -package cl.homelogic.platform.common - -@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") -actual object Platform { - actual fun getType() = PlatformTypes.IOS -} diff --git a/core/common/src/iosMain/kotlin/cl/homelogic/platform/common/logging/Trace.ios.kt b/core/common/src/iosMain/kotlin/cl/homelogic/platform/common/logging/Trace.ios.kt deleted file mode 100644 index 90dd733..0000000 --- a/core/common/src/iosMain/kotlin/cl/homelogic/platform/common/logging/Trace.ios.kt +++ /dev/null @@ -1,12 +0,0 @@ -package cl.homelogic.platform.common.logging - -import platform.Foundation.NSLog - -internal actual fun logPlatform( - severity: Severity, - tag: String, - message: String, -) { - if (severity == Severity.None) return - NSLog("Trace - $tag [${severity.name}]: $message") -} diff --git a/core/common/src/iosMain/kotlin/cl/homelogic/platform/common/settings/SettingsSource.ios.kt b/core/common/src/iosMain/kotlin/cl/homelogic/platform/common/settings/SettingsSource.ios.kt deleted file mode 100644 index d4c144e..0000000 --- a/core/common/src/iosMain/kotlin/cl/homelogic/platform/common/settings/SettingsSource.ios.kt +++ /dev/null @@ -1,16 +0,0 @@ -package cl.homelogic.platform.common.settings - -import com.russhwolf.settings.NSUserDefaultsSettings -import com.russhwolf.settings.Settings -import platform.Foundation.NSUserDefaults - -class IOSSettingsFactory : ISettingsFactory { - override fun createSettings(name: String?): Settings { - val userDefaults = if (name != null) { - NSUserDefaults(suiteName = name) - } else { - NSUserDefaults.standardUserDefaults - } - return NSUserDefaultsSettings(userDefaults) - } -} diff --git a/core/designsystem/build.gradle.kts b/core/designsystem/build.gradle.kts deleted file mode 100644 index dccbcc3..0000000 --- a/core/designsystem/build.gradle.kts +++ /dev/null @@ -1,22 +0,0 @@ -group = "dev.carlosmartino.designsystem" - -plugins { - alias(libs.plugins.kotlinDevKit) - alias(libs.plugins.composeDevKit) -} - -kotlin { - sourceSets { - commonMain.dependencies { - implementation(projects.core.common) - api(libs.insetsx) - implementation(libs.markdown) - } - } -} - -compose.resources { - publicResClass = true - packageOfResClass = "dev.carlosmartino.designsystem.resources" - generateResClass = always -} diff --git a/core/designsystem/src/androidMain/kotlin/cl/homelogic/platform/designsystem/themes/StatusBarManager.android.kt b/core/designsystem/src/androidMain/kotlin/cl/homelogic/platform/designsystem/themes/StatusBarManager.android.kt deleted file mode 100644 index 1f3263a..0000000 --- a/core/designsystem/src/androidMain/kotlin/cl/homelogic/platform/designsystem/themes/StatusBarManager.android.kt +++ /dev/null @@ -1,39 +0,0 @@ -package cl.homelogic.platform.designsystem.themes - -import cl.homelogic.platform.common.logging.Trace -import cl.homelogic.platform.common.logging.TreeRoots -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch - -enum class StatusBarState { - LIGHT, - DARK, -} - -@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") -actual class StatusBarManager : IStatusBarManager { - private val _coroutineScope = CoroutineScope(Dispatchers.Default) - - companion object { - private val _statusBarState = MutableStateFlow(StatusBarState.LIGHT) - val state: StateFlow = _statusBarState.asStateFlow() - } - - override fun lightMode() { - Trace.d(TreeRoots.DesignSystem, "Android - requesting light status bar") - _coroutineScope.launch { - _statusBarState.emit(StatusBarState.LIGHT) - } - } - - override fun darkMode() { - Trace.d(TreeRoots.DesignSystem, "Android - requesting dark status bar") - _coroutineScope.launch { - _statusBarState.emit(StatusBarState.DARK) - } - } -} diff --git a/core/designsystem/src/commonMain/composeResources/font/Manrope-Bold.ttf b/core/designsystem/src/commonMain/composeResources/font/Manrope-Bold.ttf deleted file mode 100644 index 98c1c3d..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/Manrope-Bold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/Manrope-ExtraBold.ttf b/core/designsystem/src/commonMain/composeResources/font/Manrope-ExtraBold.ttf deleted file mode 100644 index 369d719..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/Manrope-ExtraBold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/Manrope-ExtraLight.ttf b/core/designsystem/src/commonMain/composeResources/font/Manrope-ExtraLight.ttf deleted file mode 100644 index 8915d96..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/Manrope-ExtraLight.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/Manrope-Light.ttf b/core/designsystem/src/commonMain/composeResources/font/Manrope-Light.ttf deleted file mode 100644 index 4942924..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/Manrope-Light.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/Manrope-Medium.ttf b/core/designsystem/src/commonMain/composeResources/font/Manrope-Medium.ttf deleted file mode 100644 index 5eda9ec..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/Manrope-Medium.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/Manrope-Regular.ttf b/core/designsystem/src/commonMain/composeResources/font/Manrope-Regular.ttf deleted file mode 100644 index 1a07233..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/Manrope-Regular.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/Manrope-SemiBold.ttf b/core/designsystem/src/commonMain/composeResources/font/Manrope-SemiBold.ttf deleted file mode 100644 index b6e9c20..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/Manrope-SemiBold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Bold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Bold.ttf deleted file mode 100644 index 9147fd3..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Bold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-ExtraLight.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-ExtraLight.ttf deleted file mode 100644 index 7b3160e..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-ExtraLight.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Light.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Light.ttf deleted file mode 100644 index 9fbc5e8..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Light.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Medium.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Medium.ttf deleted file mode 100644 index 49bb0f6..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Medium.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Regular.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Regular.ttf deleted file mode 100644 index 93da980..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Regular.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-SemiBold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-SemiBold.ttf deleted file mode 100644 index f817212..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-SemiBold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Thin.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Thin.ttf deleted file mode 100644 index a8d0472..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined-Thin.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Bold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Bold.ttf deleted file mode 100644 index 8dbdcdd..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Bold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-ExtraLight.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-ExtraLight.ttf deleted file mode 100644 index 14a25e7..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-ExtraLight.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Light.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Light.ttf deleted file mode 100644 index 36e2303..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Light.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Medium.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Medium.ttf deleted file mode 100644 index ff9985c..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Medium.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Regular.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Regular.ttf deleted file mode 100644 index 3a35182..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Regular.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-SemiBold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-SemiBold.ttf deleted file mode 100644 index 0a9cfda..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-SemiBold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Thin.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Thin.ttf deleted file mode 100644 index dd101e6..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsOutlined_Filled-Thin.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Bold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Bold.ttf deleted file mode 100644 index c557821..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Bold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-ExtraLight.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-ExtraLight.ttf deleted file mode 100644 index 8f16aad..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-ExtraLight.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Light.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Light.ttf deleted file mode 100644 index 616cc6d..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Light.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Medium.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Medium.ttf deleted file mode 100644 index 3131034..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Medium.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Regular.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Regular.ttf deleted file mode 100644 index 10aa9e5..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Regular.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-SemiBold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-SemiBold.ttf deleted file mode 100644 index 3a0ebae..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-SemiBold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Thin.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Thin.ttf deleted file mode 100644 index 6d0d193..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded-Thin.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Bold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Bold.ttf deleted file mode 100644 index 52756dd..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Bold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-ExtraLight.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-ExtraLight.ttf deleted file mode 100644 index 602143f..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-ExtraLight.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Light.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Light.ttf deleted file mode 100644 index f2b9493..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Light.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Medium.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Medium.ttf deleted file mode 100644 index ce89979..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Medium.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Regular.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Regular.ttf deleted file mode 100644 index ba348e7..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Regular.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-SemiBold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-SemiBold.ttf deleted file mode 100644 index e74f221..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-SemiBold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Thin.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Thin.ttf deleted file mode 100644 index 534e110..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsRounded_Filled-Thin.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Bold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Bold.ttf deleted file mode 100644 index b896e67..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Bold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-ExtraLight.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-ExtraLight.ttf deleted file mode 100644 index 2a2b86b..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-ExtraLight.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Light.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Light.ttf deleted file mode 100644 index f2560ec..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Light.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Medium.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Medium.ttf deleted file mode 100644 index 29af14d..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Medium.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Regular.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Regular.ttf deleted file mode 100644 index 6f10212..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Regular.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-SemiBold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-SemiBold.ttf deleted file mode 100644 index 007c3d4..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-SemiBold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Thin.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Thin.ttf deleted file mode 100644 index 608d1d1..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp-Thin.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Bold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Bold.ttf deleted file mode 100644 index b5a6850..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Bold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-ExtraLight.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-ExtraLight.ttf deleted file mode 100644 index 3f99ab6..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-ExtraLight.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Light.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Light.ttf deleted file mode 100644 index 66d138b..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Light.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Medium.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Medium.ttf deleted file mode 100644 index 0beba47..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Medium.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Regular.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Regular.ttf deleted file mode 100644 index 2cc8244..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Regular.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-SemiBold.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-SemiBold.ttf deleted file mode 100644 index 67f7079..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-SemiBold.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Thin.ttf b/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Thin.ttf deleted file mode 100644 index 305c2e6..0000000 Binary files a/core/designsystem/src/commonMain/composeResources/font/MaterialSymbolsSharp_Filled-Thin.ttf and /dev/null differ diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/BottomSafeZone.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/BottomSafeZone.kt deleted file mode 100644 index 0b350d2..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/BottomSafeZone.kt +++ /dev/null @@ -1,12 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import cl.homelogic.platform.designsystem.foundations.Sizes - -@Composable -fun BottomSafeZone() { - Spacer(modifier = Modifier.height(Sizes.ScreenInset.Bottom)) -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/DescriptionCard.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/DescriptionCard.kt deleted file mode 100644 index b184025..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/DescriptionCard.kt +++ /dev/null @@ -1,86 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.LocalIndication -import androidx.compose.foundation.background -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import cl.homelogic.platform.designsystem.extensions.conditionalClickable -import cl.homelogic.platform.designsystem.extensions.scaledByFontSize -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Shapes -import cl.homelogic.platform.designsystem.foundations.Sizes - -@Composable -fun DescriptionCard( - modifier: Modifier = Modifier, - title: String, - subtitle: String = "", - onClick: (() -> Unit)? = null, - content: @Composable () -> Unit, -) { - val interactionSource = remember { MutableInteractionSource() } - - Surface( - modifier = modifier - .padding(top = Padding.tiny, bottom = Padding.small) - .clip(Shapes.RoundCorner.regular) - .wrapContentSize(Alignment.TopCenter, false) - .conditionalClickable( - interactionSource = interactionSource, - indication = LocalIndication.current, - onClick = onClick, - ), - shape = Shapes.RoundCorner.regular, - border = BorderStroke( - width = Sizes.Borders.Regular, - color = MaterialTheme.colorScheme.outline, - ), - ) { - Column( - modifier = Modifier.wrapContentSize(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - ) { - content() - Column( - modifier = Modifier - .background(MaterialTheme.colorScheme.surfaceVariant) - .padding(Padding.regular) - .height(Sizes.Containers.Small.scaledByFontSize()) - .fillMaxWidth(), - ) { - Text( - text = title, - textAlign = TextAlign.Start, - style = typography.labelLarge, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - Text( - text = subtitle, - textAlign = TextAlign.Start, - style = typography.labelMedium, - maxLines = 2, - overflow = TextOverflow.Ellipsis, - ) - } - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/Divider.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/Divider.kt deleted file mode 100644 index 7dbb6da..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/Divider.kt +++ /dev/null @@ -1,20 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import cl.homelogic.platform.designsystem.foundations.Sizes - -@Composable -fun Divider(modifier: Modifier = Modifier) { - Box( - modifier = modifier - .fillMaxWidth() - .height(Sizes.Stroke.Regular) - .background(MaterialTheme.colorScheme.outline), - ) -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/Markdown.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/Markdown.kt deleted file mode 100644 index 4c94d28..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/Markdown.kt +++ /dev/null @@ -1,856 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.foundation.background -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.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.text.selection.SelectionContainer -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Immutable -import androidx.compose.runtime.mutableStateMapOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.LinkAnnotation -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextDecoration -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Shapes -import org.intellij.markdown.MarkdownElementTypes -import org.intellij.markdown.MarkdownTokenTypes -import org.intellij.markdown.ast.ASTNode -import org.intellij.markdown.ast.getTextInNode -import org.intellij.markdown.flavours.gfm.GFMElementTypes -import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor -import org.intellij.markdown.parser.MarkdownParser - -@Immutable -data class MarkdownTypography( - val text: TextStyle, - val code: TextStyle, - val inlineCode: TextStyle, - val h1: TextStyle, - val h2: TextStyle, - val h3: TextStyle, - val h4: TextStyle, - val h5: TextStyle, - val h6: TextStyle, - val quote: TextStyle, - val paragraph: TextStyle, - val ordered: TextStyle, - val bullet: TextStyle, - val list: TextStyle, - val textLink: TextLinkStates, - val table: TextStyle, -) - -@Immutable -data class MarkdownColors( - val codeBackground: Color, - val codeText: Color, - val dividerColor: Color, - val inlineCodeBackground: Color, - val inlineCodeText: Color, - val linkText: Color, - val tableBackground: Color, - val tableText: Color, - val text: Color, -) - -@Immutable -data class TextLinkStates( - val normal: TextStyle, - val visited: TextStyle, -) - -@Immutable -private data class MarkdownContentData( - val node: ASTNode, - val content: String, - val colors: MarkdownColors, - val typography: MarkdownTypography, - val level: Int = 0, -) - -@Composable -fun Markdown( - modifier: Modifier = Modifier, - text: String, - colors: MarkdownColors = rememberDefaultMarkdownColors(), - typography: MarkdownTypography = rememberDefaultMarkdownTypography(), -) { - val flavour = remember { GFMFlavourDescriptor() } - val parser = remember { MarkdownParser(flavour) } - - val markdownTree = remember(text) { parser.buildMarkdownTreeFromString(text) } - - val markdownContent = remember(markdownTree, text, colors, typography) { - MarkdownContentData(markdownTree, text, colors, typography) - } - - val annotatedStringCache = remember { mutableStateMapOf() } - - val listState = rememberLazyListState() - - SelectionContainer { - Column { - OptimizedMarkdownContent( - data = markdownContent, - stringCache = annotatedStringCache, - ) - } - } -} - -@Composable -private fun rememberDefaultMarkdownColors(): MarkdownColors { - val colorScheme = MaterialTheme.colorScheme - return remember { - MarkdownColors( - codeBackground = colorScheme.surfaceVariant, - codeText = colorScheme.onSurfaceVariant, - dividerColor = colorScheme.outline, - inlineCodeBackground = colorScheme.surfaceVariant, - inlineCodeText = colorScheme.onSurfaceVariant, - linkText = colorScheme.tertiary, - tableBackground = colorScheme.surface, - tableText = colorScheme.onSurface, - text = colorScheme.onPrimary, - ) - } -} - -@Composable -private fun rememberDefaultMarkdownTypography(): MarkdownTypography { - val materialTypography = MaterialTheme.typography - return remember { - MarkdownTypography( - bullet = materialTypography.bodySmall, - code = materialTypography.bodyMedium, - h1 = materialTypography.headlineLarge, - h2 = materialTypography.headlineMedium, - h3 = materialTypography.headlineSmall, - h4 = materialTypography.titleLarge, - h5 = materialTypography.titleMedium, - h6 = materialTypography.bodyLarge, - inlineCode = materialTypography.bodyLarge, - list = materialTypography.bodyMedium, - ordered = materialTypography.bodyMedium, - paragraph = materialTypography.bodyMedium, - quote = materialTypography.bodyMedium.copy( - fontStyle = FontStyle.Italic, - ), - table = materialTypography.bodySmall, - text = materialTypography.bodyMedium, - textLink = TextLinkStates( - normal = materialTypography.bodyMedium.copy( - textDecoration = TextDecoration.Underline, - ), - visited = materialTypography.bodyMedium.copy( - textDecoration = TextDecoration.Underline, - ), - ), - ) - } -} - -@Composable -private fun OptimizedMarkdownContent( - data: MarkdownContentData, - stringCache: MutableMap, - maxDepth: Int = 10, -) { - if (data.level > maxDepth) return - - for (child in data.node.children) { - val nodeKey = "${child.hashCode()}-${data.level}" - val childData = remember(child, data) { - data.copy(node = child, level = data.level + 1) - } - - when (child.type) { - MarkdownElementTypes.PARAGRAPH -> { - OptimizedParagraph(stringCache, nodeKey, child, data) - } - - MarkdownElementTypes.ATX_1, - MarkdownElementTypes.ATX_2, - MarkdownElementTypes.ATX_3, - MarkdownElementTypes.ATX_4, - MarkdownElementTypes.ATX_5, - MarkdownElementTypes.ATX_6, - -> { - OptimizedHeading( - childData = childData, - nodeKey = nodeKey, - stringCache = stringCache, - ) - } - - MarkdownElementTypes.UNORDERED_LIST -> { - OptimizedUnorderedList( - childData = childData, - stringCache = stringCache, - ) - } - - MarkdownElementTypes.ORDERED_LIST -> { - OptimizedOrderedList( - childData = childData, - stringCache = stringCache, - ) - } - - MarkdownElementTypes.BLOCK_QUOTE -> { - OptimizedBlockQuote( - childData = childData, - stringCache = stringCache, - ) - } - - MarkdownElementTypes.CODE_FENCE, - MarkdownElementTypes.CODE_BLOCK, - -> { - OptimizedCodeBlock(childData = childData) - } - - MarkdownElementTypes.HTML_BLOCK -> { - OptimizedHtmlBlock(childData = childData) - } - - GFMElementTypes.TABLE -> { - OptimizedTable( - childData = childData, - stringCache = stringCache, - ) - } - } - } -} - -@Composable -private fun OptimizedParagraph( - stringCache: MutableMap, - nodeKey: String, - child: ASTNode, - data: MarkdownContentData, -) { - val paragraphModifier = remember { - Modifier.padding( - vertical = Padding.small, - horizontal = Padding.tiny, - ) - } - - val annotatedString = stringCache.getOrPut(nodeKey) { - buildAnnotatedString { - renderInlineContent(child, data.content, data.colors, data.typography) - } - } - - Text( - text = annotatedString, - style = data.typography.paragraph, - color = data.colors.text, - modifier = paragraphModifier, - ) -} - -@Composable -private fun OptimizedHeading( - childData: MarkdownContentData, - nodeKey: String, - stringCache: MutableMap, -) { - val (style, topPadding, bottomPadding) = remember(childData.node.type) { - when (childData.node.type) { - MarkdownElementTypes.ATX_1 -> Triple( - childData.typography.h1, - Padding.regular, - Padding.small, - ) - - MarkdownElementTypes.ATX_2 -> Triple( - childData.typography.h2, - Padding.small, - Padding.small, - ) - - MarkdownElementTypes.ATX_3 -> Triple( - childData.typography.h3, - Padding.small, - Padding.small, - ) - - MarkdownElementTypes.ATX_4 -> Triple( - childData.typography.h4, - Padding.small, - Padding.tiny, - ) - - MarkdownElementTypes.ATX_5 -> Triple( - childData.typography.h5, - Padding.small, - Padding.tiny, - ) - - MarkdownElementTypes.ATX_6 -> Triple( - childData.typography.h6, - Padding.small, - Padding.tiny, - ) - - else -> Triple( - childData.typography.text, - Padding.small, - Padding.small, - ) - } - } - - val headingModifier = remember(topPadding, bottomPadding) { - Modifier.padding(top = topPadding, bottom = bottomPadding) - } - - val headingText = stringCache.getOrPut(nodeKey) { - buildAnnotatedString { - for (headerChild in childData.node.children) { - if (headerChild.type != MarkdownTokenTypes.ATX_HEADER && - headerChild.type != MarkdownTokenTypes.EOL - ) { - renderInlineContent( - headerChild, - childData.content, - childData.colors, - childData.typography, - ) - } - } - } - } - - Text( - text = headingText, - style = style, - color = childData.colors.text, - modifier = headingModifier, - ) -} - -@Composable -private fun OptimizedUnorderedList( - childData: MarkdownContentData, - stringCache: MutableMap, -) { - val listModifier = remember { - Modifier - .padding(vertical = Padding.small) - .padding(start = Padding.regular) - } - - Column(modifier = listModifier) { - for (item in childData.node.children) { - if (item.type == MarkdownElementTypes.LIST_ITEM) { - val itemData = remember(item, childData) { - childData.copy(node = item) - } - OptimizedListItem( - itemData = itemData, - stringCache = stringCache, - isOrdered = false, - index = 0, - ) - } - } - } -} - -@Composable -private fun OptimizedOrderedList( - childData: MarkdownContentData, - stringCache: MutableMap, -) { - val listModifier = remember { - Modifier - .padding(vertical = Padding.small) - .padding(start = Padding.regular) - } - - Column(modifier = listModifier) { - childData.node.children.forEachIndexed { index, item -> - if (item.type == MarkdownElementTypes.LIST_ITEM) { - val itemData = remember(item, childData) { - childData.copy(node = item) - } - OptimizedListItem( - itemData = itemData, - stringCache = stringCache, - isOrdered = true, - index = index + 1, - ) - } - } - } -} - -@Composable -private fun OptimizedListItem( - itemData: MarkdownContentData, - stringCache: MutableMap, - isOrdered: Boolean, - index: Int, -) { - val itemModifier = remember { Modifier.padding(vertical = Padding.tiny) } - - Row( - modifier = itemModifier, - verticalAlignment = Alignment.Top, - ) { - Text( - text = if (isOrdered) "$index. " else "• ", - style = if (isOrdered) itemData.typography.ordered else itemData.typography.bullet, - color = itemData.colors.text, - ) - - Column { - for (itemChild in itemData.node.children) { - val nodeKey = "${itemChild.hashCode()}-${itemData.level}" - - when (itemChild.type) { - MarkdownElementTypes.PARAGRAPH -> { - val text = stringCache.getOrPut(nodeKey) { - buildAnnotatedString { - renderInlineContent( - itemChild, - itemData.content, - itemData.colors, - itemData.typography, - ) - } - } - - Text( - text = text, - style = itemData.typography.list, - color = itemData.colors.text, - ) - } - - MarkdownElementTypes.UNORDERED_LIST, - MarkdownElementTypes.ORDERED_LIST, - -> { - val childData = remember(itemChild, itemData) { - itemData.copy(node = itemChild) - } - OptimizedMarkdownContent( - data = childData, - stringCache = stringCache, - ) - } - } - } - } - } -} - -@Composable -private fun OptimizedBlockQuote( - childData: MarkdownContentData, - stringCache: MutableMap, -) { - val blockQuoteModifier = remember { Modifier.padding(vertical = Padding.small) } - val dividerModifier = remember { - Modifier - .width(Padding.tiny) - .wrapContentHeight() - .background(childData.colors.dividerColor) - } - val contentModifier = remember { Modifier.padding(start = Padding.regular) } - - Row( - modifier = blockQuoteModifier, - verticalAlignment = Alignment.Top, - ) { - Box(modifier = dividerModifier) - - Column(modifier = contentModifier) { - for (quoteChild in childData.node.children) { - val nodeKey = "${quoteChild.hashCode()}-${childData.level}" - - if (quoteChild.type == MarkdownElementTypes.PARAGRAPH) { - val text = stringCache.getOrPut(nodeKey) { - buildAnnotatedString { - renderInlineContent( - quoteChild, - childData.content, - childData.colors, - childData.typography, - ) - } - } - - Text( - text = text, - style = childData.typography.quote, - color = childData.colors.text, - ) - } else { - val innerChildData = remember(quoteChild, childData) { - childData.copy(node = quoteChild) - } - OptimizedMarkdownContent( - data = innerChildData, - stringCache = stringCache, - ) - } - } - } - } -} - -@Composable -private fun OptimizedCodeBlock(childData: MarkdownContentData) { - val codeContent = remember(childData.node, childData.content) { - when (childData.node.type) { - MarkdownElementTypes.CODE_FENCE -> { - childData.node.children - .firstOrNull { it.type == MarkdownTokenTypes.CODE_FENCE_CONTENT } - ?.getTextInNode(childData.content) - ?.toString() ?: "" - } - - MarkdownElementTypes.CODE_BLOCK -> { - childData.node.children - .firstOrNull { it.type == MarkdownTokenTypes.CODE_LINE } - ?.getTextInNode(childData.content) - ?.toString() ?: "" - } - - else -> "" - } - } - - val codeBlockModifier = remember { - Modifier - .clip(Shapes.RoundCorner.regular) - .background(childData.colors.codeBackground) - .fillMaxWidth() - .padding(vertical = Padding.small) - } - - val textModifier = remember { Modifier.padding(Padding.regular) } - - Surface( - modifier = codeBlockModifier, - color = childData.colors.codeBackground, - ) { - Text( - text = codeContent, - style = childData.typography.code, - color = childData.colors.codeText, - modifier = textModifier, - ) - } -} - -@Composable -private fun OptimizedHtmlBlock(childData: MarkdownContentData) { - val htmlContent = remember(childData.node, childData.content) { - childData.node.getTextInNode(childData.content).toString() - } - - val htmlBlockModifier = remember { Modifier.padding(vertical = Padding.small) } - - Text( - text = htmlContent, - style = childData.typography.text, - color = childData.colors.text, - modifier = htmlBlockModifier, - ) -} - -@Composable -private fun OptimizedTable( - childData: MarkdownContentData, - stringCache: MutableMap, -) { - val tableModifier = remember { - Modifier - .fillMaxWidth() - .padding(vertical = Padding.small) - } - - val tableContentModifier = remember { Modifier.padding(Padding.small) } - - Surface( - color = childData.colors.tableBackground, - modifier = tableModifier, - ) { - Column(modifier = tableContentModifier) { - for (row in childData.node.children) { - if (row.type == GFMElementTypes.HEADER || - row.type == GFMElementTypes.ROW - ) { - val rowData = remember(row, childData) { - childData.copy(node = row) - } - OptimizedTableRow( - rowData = rowData, - stringCache = stringCache, - ) - - if (row.type == GFMElementTypes.HEADER) { - Divider(modifier = Modifier.padding(bottom = Padding.small)) - } - } - } - } - } -} - -@Composable -private fun OptimizedTableRow( - rowData: MarkdownContentData, - stringCache: MutableMap, -) { - val rowModifier = remember { Modifier.fillMaxWidth() } - - val cellNodes = remember(rowData.node) { - rowData.node.children.filter { - it.type != GFMElementTypes.HEADER && - it.type != GFMElementTypes.ROW && - it.type != GFMElementTypes.TABLE - } - } - - Row( - modifier = rowModifier, - horizontalArrangement = Arrangement.SpaceBetween, - ) { - cellNodes.forEach { cellNode -> - val cellData = remember(cellNode, rowData) { - rowData.copy(node = cellNode) - } - - val isHeader = remember(rowData.node.type) { - rowData.node.type == GFMElementTypes.HEADER - } - - OptimizedTableCell( - modifier = Modifier.weight(1f), - cellData = cellData, - stringCache = stringCache, - isHeader = isHeader, - ) - } - } -} - -@Composable -private fun OptimizedTableCell( - modifier: Modifier = Modifier, - cellData: MarkdownContentData, - stringCache: MutableMap, - isHeader: Boolean, -) { - val nodeKey = "${cellData.node.hashCode()}-${cellData.level}" - val cellModifier = remember { modifier.padding(Padding.tiny) } - - val cellText = stringCache.getOrPut(nodeKey) { - buildAnnotatedString { - renderInlineContent( - cellData.node, - cellData.content, - cellData.colors, - cellData.typography, - ) - } - } - - val style = remember(isHeader) { - if (isHeader) cellData.typography.h4 else cellData.typography.table - } - - val fontWeight = remember(isHeader) { - if (isHeader) FontWeight.Bold else FontWeight.Normal - } - - Text( - text = cellText, - style = style, - color = cellData.colors.tableText, - fontWeight = fontWeight, - modifier = cellModifier, - ) -} - -private fun AnnotatedString.Builder.renderInlineContent( - node: ASTNode, - content: String, - colors: MarkdownColors, - typography: MarkdownTypography, -) { - for (child in node.children) { - when (child.type) { - MarkdownTokenTypes.TEXT, MarkdownTokenTypes.WHITE_SPACE -> { - append(child.getTextInNode(content)) - } - - MarkdownElementTypes.EMPH -> { - renderEmphasis(child, content, colors, typography) - } - - MarkdownElementTypes.STRONG -> { - renderStrong(child, content, colors, typography) - } - - MarkdownElementTypes.CODE_SPAN -> { - renderCodeSpan(child, content, colors) - } - - MarkdownElementTypes.INLINE_LINK -> { - renderInlineLink(child, content, colors, typography) - } - - MarkdownElementTypes.FULL_REFERENCE_LINK, - MarkdownElementTypes.SHORT_REFERENCE_LINK, - -> { - renderReferenceLink(child, content, colors, typography) - } - - MarkdownTokenTypes.HARD_LINE_BREAK -> { - append("\n") - } - - else -> { - renderInlineContent(child, content, colors, typography) - } - } - } -} - -private fun AnnotatedString.Builder.renderEmphasis( - node: ASTNode, - content: String, - colors: MarkdownColors, - typography: MarkdownTypography, -) { - pushStyle(SpanStyle(fontStyle = FontStyle.Italic)) - renderInlineContent(node, content, colors, typography) - pop() -} - -private fun AnnotatedString.Builder.renderStrong( - node: ASTNode, - content: String, - colors: MarkdownColors, - typography: MarkdownTypography, -) { - pushStyle(SpanStyle(fontWeight = FontWeight.Bold)) - renderInlineContent(node, content, colors, typography) - pop() -} - -private fun AnnotatedString.Builder.renderCodeSpan( - node: ASTNode, - content: String, - colors: MarkdownColors, -) { - pushStyle( - SpanStyle( - background = colors.inlineCodeBackground, - color = colors.inlineCodeText, - fontFamily = FontFamily.Monospace, - ), - ) - append("${node.getTextInNode(content).trim('`')}") - pop() -} - -private fun AnnotatedString.Builder.renderInlineLink( - node: ASTNode, - content: String, - colors: MarkdownColors, - typography: MarkdownTypography, -) { - val linkText = node.children.firstOrNull { it.type == MarkdownElementTypes.LINK_TEXT } - val linkDestination = - node.children.firstOrNull { it.type == MarkdownElementTypes.LINK_DESTINATION } - val url = linkDestination?.getTextInNode(content)?.trim('(', ')')?.toString() ?: "" - - val startPosition = length - - pushStyle(SpanStyle(color = colors.linkText)) - - if (linkText != null) { - val linkTextContent = linkText.getTextInNode(content) - if (linkTextContent.isNotEmpty()) { - append(linkTextContent) - } else { - for (textChild in linkText.children) { - if (textChild.type != MarkdownTokenTypes.LBRACKET && - textChild.type != MarkdownTokenTypes.RBRACKET - ) { - renderInlineContent(textChild, content, colors, typography) - } - } - } - } else { - append(url) - } - - if (length > startPosition) { - addLink( - url = LinkAnnotation.Url(url = url), - start = startPosition, - end = length, - ) - } - - pop() -} - -private fun AnnotatedString.Builder.renderReferenceLink( - node: ASTNode, - content: String, - colors: MarkdownColors, - typography: MarkdownTypography, -) { - val linkText = node.children.firstOrNull { it.type == MarkdownElementTypes.LINK_TEXT } - - pushStyle( - SpanStyle( - color = colors.linkText, - textDecoration = TextDecoration.Underline, - ), - ) - - if (linkText != null) { - for (textChild in linkText.children) { - if (textChild.type != MarkdownTokenTypes.LBRACKET && - textChild.type != MarkdownTokenTypes.RBRACKET - ) { - renderInlineContent(textChild, content, colors, typography) - } - } - } - - pop() -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SectionTitle.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SectionTitle.kt deleted file mode 100644 index 8845581..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SectionTitle.kt +++ /dev/null @@ -1,36 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextOverflow -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Sizes - -@Composable -fun SectionTitle( - text: String, - modifier: Modifier = Modifier, -) { - Box( - contentAlignment = Alignment.BottomStart, - modifier = modifier - .fillMaxWidth() - .height(Sizes.Containers.Small) - .padding(bottom = Padding.small), - ) { - Box { - Text( - text = text, - style = typography.headlineMedium, - overflow = TextOverflow.Visible, - ) - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SegmentedControl.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SegmentedControl.kt deleted file mode 100644 index 19d7034..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SegmentedControl.kt +++ /dev/null @@ -1,145 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.spring -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.shadow -import androidx.compose.ui.layout.onSizeChanged -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.IntOffset -import cl.homelogic.platform.designsystem.foundations.FeedbackType -import cl.homelogic.platform.designsystem.foundations.LocalHapticManager -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Shapes -import cl.homelogic.platform.designsystem.foundations.Sizes -import kotlin.math.abs -import kotlin.math.roundToInt - -@Composable -fun SegmentedControl( - modifier: Modifier = Modifier, - items: List, - initialSelectedIndex: Int, - onSelectedIndexChange: (Int) -> Unit, -) { - var selectedIndex by remember { mutableIntStateOf(initialSelectedIndex) } - - val density = LocalDensity.current - val haptic = LocalHapticManager.current - var componentWidth by remember { mutableStateOf(0) } - val itemWidth = remember(componentWidth) { componentWidth.toFloat() / items.size } - val pillOffset by animateFloatAsState( - targetValue = itemWidth * selectedIndex, - animationSpec = spring( - dampingRatio = 0.83f, - stiffness = Spring.StiffnessMediumLow, - ), - label = "SegmentedControl-pillOffset", - ) - - Box( - modifier = modifier - .height(Sizes.Containers.Small) - .clip(Shapes.RoundCorner.regular) - .background(MaterialTheme.colorScheme.surfaceVariant) - .padding(Padding.tiny) - .onSizeChanged { size -> - if (componentWidth != size.width) { - componentWidth = size.width - } - }, - ) { - // Animated Pill - Box( - modifier = Modifier - .offset { IntOffset(pillOffset.roundToInt(), 0) } - .width(with(density) { itemWidth.toDp() }) - .fillMaxHeight() - .shadow(Sizes.Shadows.Regular, shape = Shapes.RoundCorner.small) - .clip(Shapes.RoundCorner.small) - .background(MaterialTheme.colorScheme.primaryContainer), - ) - - SegmentedControlItems(items, selectedIndex) { newIndex -> - if (newIndex != selectedIndex) { - // Do a stronger vibration if the pill moves more than - val difference = abs(newIndex - selectedIndex) - if (difference < 3) { - haptic.performFeedback(FeedbackType.SegmentTick) - } else { - haptic.performFeedback(FeedbackType.LongPress) - } - } - selectedIndex = newIndex - onSelectedIndexChange(newIndex) - } - } -} - -@Composable -private fun SegmentedControlItems( - items: List, - selectedIndex: Int, - onSelectedIndexChange: (Int) -> Unit, -) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceEvenly, - ) { - items.forEachIndexed { index, item -> - Box( - modifier = Modifier - .weight(1f) - .fillMaxHeight() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - ) { - onSelectedIndexChange(index) - }.padding(horizontal = Padding.small), - contentAlignment = Alignment.Center, - ) { - Text( - text = item, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - color = if (selectedIndex == index) { - MaterialTheme.colorScheme.onSurface - } else { - MaterialTheme.colorScheme.onSurfaceVariant - }, - style = if (selectedIndex == index) { - typography.bodyLarge - } else { - typography.bodyMedium - }, - ) - } - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleButton.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleButton.kt deleted file mode 100644 index 211eef2..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleButton.kt +++ /dev/null @@ -1,83 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import cl.homelogic.platform.designsystem.extensions.clickable -import cl.homelogic.platform.designsystem.extensions.scaledByFontSize -import cl.homelogic.platform.designsystem.foundations.FeedbackType -import cl.homelogic.platform.designsystem.foundations.LocalHapticManager -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Shapes -import cl.homelogic.platform.designsystem.foundations.Sizes -import cl.homelogic.platform.designsystem.foundations.Symbols - -enum class ButtonStyle { - PRIMARY, - SECONDARY, - TERTIARY, -} - -@Composable -fun SimpleButton( - modifier: Modifier = Modifier, - style: ButtonStyle = ButtonStyle.PRIMARY, - text: String = "", - leadingSymbol: Symbols? = null, - enabled: Boolean = true, - hapticFeedback: Boolean = true, - onClick: () -> Unit, -) { - val haptic = LocalHapticManager.current - - val (background, textColor) = when (style) { - ButtonStyle.PRIMARY -> { - MaterialTheme.colorScheme.tertiary to MaterialTheme.colorScheme.onTertiary - } - - ButtonStyle.SECONDARY -> { - MaterialTheme.colorScheme.tertiaryContainer to MaterialTheme.colorScheme.onSurface - } - - ButtonStyle.TERTIARY -> { - Color.Transparent to MaterialTheme.colorScheme.onSurface - } - } - - Button( - onClick = { - if (hapticFeedback) haptic.performFeedback(FeedbackType.SegmentTick) - onClick() - }, - shape = Shapes.RoundCorner.big, - enabled = enabled, - colors = ButtonDefaults.buttonColors().copy( - containerColor = background, - contentColor = textColor, - disabledContainerColor = background, - disabledContentColor = textColor, - ), - modifier = modifier - .fillMaxWidth() - .height(Sizes.Buttons.Regular.scaledByFontSize()) - .clickable(enabled), - ) { - SymbolText( - modifier = Modifier.padding(end = Padding.small), - color = textColor, - icon = leadingSymbol, - ) - Text( - text = text, - style = typography.bodyLarge, - ) - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleCard.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleCard.kt deleted file mode 100644 index 75b7bbc..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleCard.kt +++ /dev/null @@ -1,45 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.LocalIndication -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import cl.homelogic.platform.designsystem.extensions.conditionalClickable -import cl.homelogic.platform.designsystem.foundations.Shapes -import cl.homelogic.platform.designsystem.foundations.Sizes - -@Composable -fun SimpleCard( - modifier: Modifier = Modifier, - onClick: (() -> Unit)? = null, - content: @Composable () -> Unit, -) { - val interactionSource = remember { MutableInteractionSource() } - - Surface( - modifier = modifier - .wrapContentSize(Alignment.TopCenter, false) - .clip(Shapes.RoundCorner.regular) - .fillMaxWidth() - .conditionalClickable( - interactionSource = interactionSource, - indication = LocalIndication.current, - onClick = onClick, - ), - shape = Shapes.RoundCorner.regular, - border = BorderStroke( - width = Sizes.Borders.Regular, - color = MaterialTheme.colorScheme.outline, - ), - ) { - content() - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleCheckbox.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleCheckbox.kt deleted file mode 100644 index b2850cd..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleCheckbox.kt +++ /dev/null @@ -1,42 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.material3.Checkbox -import androidx.compose.material3.CheckboxDefaults -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import cl.homelogic.platform.designsystem.extensions.clickable -import cl.homelogic.platform.designsystem.foundations.FeedbackType -import cl.homelogic.platform.designsystem.foundations.LocalHapticManager - -@Composable -fun SimpleCheckbox( - checked: Boolean = false, - onCheckedChange: ((Boolean) -> Unit)? = {}, - modifier: Modifier = Modifier, - enabled: Boolean = true, -) { - val haptic = LocalHapticManager.current - - Checkbox( - checked = checked, - onCheckedChange = { - if (it) { - haptic.performFeedback(FeedbackType.ToggleOn) - } else { - haptic.performFeedback(FeedbackType.ToggleOff) - } - onCheckedChange?.invoke(it) - }, - modifier = modifier.clickable(enabled), - enabled = enabled, - colors = CheckboxDefaults.colors().copy( - checkedCheckmarkColor = MaterialTheme.colorScheme.onTertiary, - checkedBoxColor = MaterialTheme.colorScheme.tertiary, - checkedBorderColor = MaterialTheme.colorScheme.tertiary, - uncheckedBorderColor = MaterialTheme.colorScheme.outline, - disabledBorderColor = MaterialTheme.colorScheme.tertiary, - disabledCheckedBoxColor = MaterialTheme.colorScheme.tertiary, - ), - ) -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleWindow.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleWindow.kt deleted file mode 100644 index 5fcca32..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SimpleWindow.kt +++ /dev/null @@ -1,54 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.ime -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberUpdatedState -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalDensity -import cl.homelogic.platform.designsystem.foundations.Dimens -import cl.homelogic.platform.designsystem.foundations.Padding - -@Composable -fun SimpleWindow( - modifier: Modifier = Modifier.fillMaxSize(), - unbounded: Boolean = false, - topBar: @Composable () -> Unit = {}, - content: @Composable ColumnScope.() -> Unit, -) { - val imeVisible by rememberUpdatedState( - WindowInsets.ime.getBottom(LocalDensity.current) > 0, - ) - - Scaffold( - topBar = topBar, - contentWindowInsets = if (!imeVisible) { - WindowInsets( - left = Dimens.at0, - top = Dimens.at0, - right = Dimens.at0, - bottom = Dimens.at0, - ) - } else { - WindowInsets.ime - }, - modifier = modifier, - ) { padding -> - Surface(modifier = Modifier.padding(padding)) { - Column( - modifier = Modifier.padding(horizontal = Padding.big).takeIf { !unbounded } - ?: Modifier, - ) { - content() - BottomSafeZone() - } - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SymbolText.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SymbolText.kt deleted file mode 100644 index 285609f..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/atoms/SymbolText.kt +++ /dev/null @@ -1,26 +0,0 @@ -package cl.homelogic.platform.designsystem.components.atoms - -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.TextStyle -import cl.homelogic.platform.designsystem.foundations.Symbols - -@Composable -fun SymbolText( - icon: Symbols? = null, - rawIcon: String = "", - style: TextStyle = typography.displaySmall, - color: Color = MaterialTheme.colorScheme.primary, - modifier: Modifier = Modifier, -) { - Text( - modifier = modifier, - text = icon?.codePoint ?: rawIcon, - color = color, - style = style, - ) -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/IconShortcut.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/IconShortcut.kt deleted file mode 100644 index efff13f..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/IconShortcut.kt +++ /dev/null @@ -1,78 +0,0 @@ -package cl.homelogic.platform.designsystem.components.molecules - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import cl.homelogic.platform.designsystem.components.atoms.SimpleCard -import cl.homelogic.platform.designsystem.components.atoms.SymbolText -import cl.homelogic.platform.designsystem.extensions.scaledByFontSize -import cl.homelogic.platform.designsystem.foundations.Dimens -import cl.homelogic.platform.designsystem.foundations.FeedbackType -import cl.homelogic.platform.designsystem.foundations.LocalHapticManager -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Sizes -import cl.homelogic.platform.designsystem.foundations.Symbols - -@Composable -fun IconShortcut( - modifier: Modifier = Modifier, - icon: Symbols? = null, - rawIcon: String = "", - title: String, - hasNotification: Boolean = false, - onClick: (() -> Unit)? = null, -) { - val haptic = LocalHapticManager.current - - SimpleCard( - onClick = { - haptic.performFeedback(FeedbackType.SegmentTick) - onClick?.invoke() - }, - modifier = modifier, - ) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(Sizes.Buttons.Big.scaledByFontSize()), - ) { - Row( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.surfaceContainer) - .padding(start = Padding.small), - verticalAlignment = Alignment.CenterVertically, - ) { - icon?.let { SymbolText(icon = icon) } ?: SymbolText(rawIcon = rawIcon) - Spacer(modifier = Modifier.width(Sizes.Spacers.Regular)) - Text( - text = title, - style = typography.labelLarge, - ) - } - - if (hasNotification) { - Box( - modifier = Modifier - .fillMaxHeight() - .width(Dimens.at8) - .align(Alignment.TopEnd) - .background(MaterialTheme.colorScheme.tertiary), - ) - } - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/LazySectionedList.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/LazySectionedList.kt deleted file mode 100644 index c31a663..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/LazySectionedList.kt +++ /dev/null @@ -1,62 +0,0 @@ -package cl.homelogic.platform.designsystem.components.molecules - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import cl.homelogic.platform.designsystem.components.atoms.BottomSafeZone -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Sizes - -data class SectionedListItem( - val title: String, - val composables: List<@Composable () -> Unit>, -) - -@Composable -fun LazySectionedList( - modifier: Modifier = Modifier, - items: List, - addSeparator: Boolean, -) { - LazyColumn( - modifier = modifier, - ) { - items(items) { sizeGroup -> - Section(sizeGroup.title) { - Column(modifier = Modifier.fillMaxWidth()) { - sizeGroup.composables.forEachIndexed { index, item -> - Row( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight() - .padding(horizontal = Padding.small), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - item() - } - if (index < sizeGroup.composables.size - 1 && addSeparator) { - HorizontalDivider( - thickness = Sizes.Stroke.Regular, - color = MaterialTheme.colorScheme.outline, - ) - } - } - } - } - } - item { - BottomSafeZone() - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/OnboardingWindow.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/OnboardingWindow.kt deleted file mode 100644 index 4ec02d8..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/OnboardingWindow.kt +++ /dev/null @@ -1,207 +0,0 @@ -package cl.homelogic.platform.designsystem.components.molecules - -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectHorizontalDragGestures -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.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.pager.HorizontalPager -import androidx.compose.foundation.pager.rememberPagerState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -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.input.pointer.pointerInput -import cl.homelogic.platform.designsystem.components.atoms.BottomSafeZone -import cl.homelogic.platform.designsystem.components.atoms.ButtonStyle -import cl.homelogic.platform.designsystem.components.atoms.SimpleButton -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Sizes -import kotlinx.coroutines.launch - -class OnboardingNavigationContext( - val currentPage: Int, - val pageCount: Int, - private val navigateTo: suspend (Int) -> Unit, - private val restrictNavigation: (Boolean) -> Unit, -) { - val isFirstPage: Boolean get() = currentPage == 0 - val isLastPage: Boolean get() = currentPage == pageCount - 1 - - suspend fun goToNextPage() { - if (currentPage < pageCount - 1) { - navigateTo(currentPage + 1) - } - } - - suspend fun goToPreviousPage() { - if (currentPage > 0) { - navigateTo(currentPage - 1) - } - } - - fun enableNavigation() { - restrictNavigation(false) - } -} - -data class OnboardingSlide( - val restrictNavigation: Boolean = false, - val content: @Composable OnboardingNavigationContext.() -> Unit, -) - -@Composable -fun OnboardingWindow( - modifier: Modifier = Modifier, - slides: List, - continueButtonText: String, - showIndicators: Boolean = true, - onFinish: () -> Unit = {}, -) { - if (slides.isEmpty()) { - onFinish() - } - - val coroutineScope = rememberCoroutineScope() - val pagerState = rememberPagerState(pageCount = { slides.size }) - - val isLastPage = pagerState.currentPage == slides.size - 1 - val currentSlide = slides[pagerState.currentPage] - - var hasRestrictedNavigation by remember(pagerState.currentPage) { - mutableStateOf(currentSlide.restrictNavigation) - } - - val navigationContext = remember(pagerState.currentPage, hasRestrictedNavigation) { - OnboardingNavigationContext( - currentPage = pagerState.currentPage, - pageCount = slides.size, - navigateTo = { page -> pagerState.animateScrollToPage(page) }, - restrictNavigation = { hasRestrictedNavigation = it }, - ) - } - - Box( - modifier = modifier - .fillMaxSize() - .pointerInput(pagerState.currentPage, hasRestrictedNavigation) { - if (!hasRestrictedNavigation) { - detectHorizontalDragGestures( - onDragStart = {}, - onDragEnd = {}, - onDragCancel = {}, - onHorizontalDrag = { change, dragAmount -> - change.consume() - - if (dragAmount > 50 && !navigationContext.isFirstPage) { - coroutineScope.launch { - navigationContext.goToPreviousPage() - } - } else if (dragAmount < -50 && !navigationContext.isLastPage) { - coroutineScope.launch { - navigationContext.goToNextPage() - } - } - }, - ) - } - }, - ) { - Column( - modifier = Modifier.fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Box( - modifier = Modifier - .weight(1f) - .wrapContentHeight() - .fillMaxWidth(), - ) { - HorizontalPager( - state = pagerState, - modifier = Modifier.fillMaxSize(), - userScrollEnabled = !hasRestrictedNavigation, - ) { page -> - val slideNavigationContext = remember(page, pagerState.currentPage) { - OnboardingNavigationContext( - currentPage = page, - pageCount = slides.size, - navigateTo = { targetPage -> pagerState.animateScrollToPage(targetPage) }, - restrictNavigation = { - if (page == pagerState.currentPage) { - hasRestrictedNavigation = it - } - }, - ) - } - - slides[page].content(slideNavigationContext) - } - } - - if (showIndicators) { - PageIndicators( - pageCount = slides.size, - currentPage = pagerState.currentPage, - modifier = Modifier.padding(Padding.big), - ) - } - - SimpleButton( - modifier = Modifier - .fillMaxWidth() - .padding(Padding.big), - style = ButtonStyle.TERTIARY, - text = continueButtonText, - enabled = !hasRestrictedNavigation, - ) { - coroutineScope.launch { - if (isLastPage) { - onFinish() - } else { - navigationContext.goToNextPage() - } - } - } - - BottomSafeZone() - } - } -} - -@Composable -private fun PageIndicators( - pageCount: Int, - currentPage: Int, - modifier: Modifier = Modifier, -) { - Row( - horizontalArrangement = Arrangement.Center, - modifier = modifier, - ) { - repeat(pageCount) { index -> - val isSelected = index == currentPage - Box( - modifier = Modifier - .padding(horizontal = Padding.tiny) - .size(if (isSelected) Sizes.Dots.Regular else Sizes.Dots.Regular) - .background( - color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline, - shape = CircleShape, - ), - ) - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/RadioButtonSelector.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/RadioButtonSelector.kt deleted file mode 100644 index 165660e..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/RadioButtonSelector.kt +++ /dev/null @@ -1,87 +0,0 @@ -package cl.homelogic.platform.designsystem.components.molecules - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.RadioButton -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import cl.homelogic.platform.designsystem.components.atoms.SimpleCard -import cl.homelogic.platform.designsystem.foundations.FeedbackType -import cl.homelogic.platform.designsystem.foundations.LocalHapticManager -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Sizes - -data class RadioButtonItem( - val text: String, - val data: T, -) - -@Composable -fun RadioButtonSelector( - items: List>, - initialSelection: RadioButtonItem? = null, - onItemSelected: (T) -> Unit, - modifier: Modifier = Modifier, -) { - var selectedItem by remember { mutableStateOf(initialSelection) } - val haptic = LocalHapticManager.current - - Column( - modifier = modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(Sizes.Spacers.Regular), - ) { - items.forEach { item -> - SelectorOption( - item = item, - isSelected = item == selectedItem, - onSelect = { - haptic.performFeedback(FeedbackType.SegmentTick) - selectedItem = item - onItemSelected(item.data) - }, - ) - } - } -} - -@Composable -private fun SelectorOption( - item: RadioButtonItem, - isSelected: Boolean, - onSelect: () -> Unit, -) { - SimpleCard( - onClick = onSelect, - modifier = Modifier.wrapContentHeight(), - ) { - Row( - modifier = Modifier - .padding(Padding.small) - .fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - modifier = Modifier.padding(start = Padding.small), - text = item.text, - style = MaterialTheme.typography.bodyMedium, - ) - - RadioButton( - selected = isSelected, - onClick = onSelect, - ) - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/SearchBar.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/SearchBar.kt deleted file mode 100644 index c078947..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/SearchBar.kt +++ /dev/null @@ -1,113 +0,0 @@ -package cl.homelogic.platform.designsystem.components.molecules - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.defaultMinSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.text.input.ImeAction -import cl.homelogic.platform.designsystem.components.atoms.SymbolText -import cl.homelogic.platform.designsystem.extensions.intangible -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Shapes -import cl.homelogic.platform.designsystem.foundations.Sizes -import cl.homelogic.platform.designsystem.foundations.Symbols - -@Composable -fun SearchBar( - modifier: Modifier = Modifier, - hint: String = "", - onTextChange: (String) -> Unit = {}, - onSearch: (String) -> Unit = {}, -) { - var searchText by remember { mutableStateOf("") } - var isFocused by remember { mutableStateOf(false) } - val focusRequester = remember { FocusRequester() } - val focusManager = LocalFocusManager.current - - Box( - modifier = modifier - .fillMaxWidth() - .defaultMinSize(minHeight = Sizes.TextFields.Regular) - .clip(Shapes.RoundCorner.regular) - .background(MaterialTheme.colorScheme.surfaceVariant) - .clickable { - focusRequester.requestFocus() - }.padding(horizontal = Padding.regular), - contentAlignment = Alignment.CenterStart, - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth(), - ) { - SymbolText( - icon = Symbols.IconSearch, - style = MaterialTheme.typography.displayMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant, - ) - - Spacer(modifier = Modifier.width(Sizes.Spacers.Regular)) - - BasicTextField( - value = searchText, - onValueChange = { newText -> - searchText = newText - onTextChange(newText) - }, - singleLine = true, - modifier = Modifier - .fillMaxWidth() - .padding(vertical = Padding.regular) - .focusRequester(focusRequester) - .onFocusChanged { focusState -> - isFocused = focusState.isFocused - }, - textStyle = MaterialTheme.typography.bodyMedium.copy( - color = MaterialTheme.colorScheme.onSurface, - ), - keyboardOptions = KeyboardOptions( - imeAction = ImeAction.Search, - ), - keyboardActions = KeyboardActions( - onSearch = { - onSearch(searchText) - focusManager.clearFocus() - }, - ), - decorationBox = { innerTextField -> - if (searchText.isEmpty() && !isFocused) { - Text( - text = hint, - color = MaterialTheme.colorScheme.onSurfaceVariant, - style = MaterialTheme.typography.bodyMedium, - modifier = Modifier.intangible(), - ) - } else { - innerTextField() - } - }, - ) - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/Section.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/Section.kt deleted file mode 100644 index 277ec62..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/Section.kt +++ /dev/null @@ -1,15 +0,0 @@ -package cl.homelogic.platform.designsystem.components.molecules - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import cl.homelogic.platform.designsystem.components.atoms.SectionTitle - -@Composable -fun Section( - title: String, - modifier: Modifier = Modifier, - content: @Composable () -> Unit, -) { - SectionTitle(title, modifier) - content() -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/SymbolButton.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/SymbolButton.kt deleted file mode 100644 index 729c7e5..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/molecules/SymbolButton.kt +++ /dev/null @@ -1,51 +0,0 @@ -package cl.homelogic.platform.designsystem.components.molecules - -import androidx.compose.foundation.LocalIndication -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.size -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import cl.homelogic.platform.designsystem.components.atoms.SymbolText -import cl.homelogic.platform.designsystem.foundations.FeedbackType -import cl.homelogic.platform.designsystem.foundations.LocalHapticManager -import cl.homelogic.platform.designsystem.foundations.Shapes -import cl.homelogic.platform.designsystem.foundations.Sizes -import cl.homelogic.platform.designsystem.foundations.Symbols - -@Composable -fun SymbolButton( - modifier: Modifier = Modifier.size(Sizes.Buttons.Regular), - icon: Symbols, - color: Color = MaterialTheme.colorScheme.primary, - background: Color = Color.Transparent, - hapticFeedback: Boolean = true, - onClick: (() -> Unit)? = null, -) { - val haptic = LocalHapticManager.current - val interactionSource = remember { MutableInteractionSource() } - Box( - modifier = modifier - .clip(Shapes.RoundCorner.regular) - .background(background) - .clickable( - interactionSource = interactionSource, - indication = LocalIndication.current, - onClick = { - if (hapticFeedback) haptic.performFeedback(FeedbackType.SegmentTick) - onClick?.invoke() - }, - ), - contentAlignment = Alignment.Center, - ) { - SymbolText(icon = icon, style = typography.displaySmall, color = color) - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/organisms/Header.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/organisms/Header.kt deleted file mode 100644 index e13621b..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/organisms/Header.kt +++ /dev/null @@ -1,213 +0,0 @@ -package cl.homelogic.platform.designsystem.components.organisms - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import cl.homelogic.platform.designsystem.components.molecules.SymbolButton -import cl.homelogic.platform.designsystem.extensions.requirePrecondition -import cl.homelogic.platform.designsystem.foundations.Padding -import cl.homelogic.platform.designsystem.foundations.Sizes -import cl.homelogic.platform.designsystem.foundations.Symbols - -sealed class HeaderTypes { - data class Home( - val title: String, - val onSettings: () -> Unit, - ) : HeaderTypes() - - data class SubHome( - val title: String, - ) : HeaderTypes() - - data class Step( - val title: String, - val onBack: () -> Unit, - ) : HeaderTypes() - - data class Modal( - val onClosed: () -> Unit, - ) : HeaderTypes() - - data class Flex( - val title: String, - val leftShortcuts: List, - val rightShortcuts: List, - ) : HeaderTypes() { - init { - requirePrecondition(leftShortcuts.size <= 3) - requirePrecondition(rightShortcuts.size <= 3) - } - } -} - -data class FlexHeaderShortcut( - val icon: Symbols, - val onClick: () -> Unit, -) - -@Composable -fun Header( - type: HeaderTypes, - showDivider: Boolean = true, - modifier: Modifier = Modifier, -) { - Surface( - modifier = modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surface) - .height(Sizes.Header.Regular), - ) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center, - ) { - when (type) { - is HeaderTypes.Home -> buildHomeHeader(type) - is HeaderTypes.SubHome -> buildSubHomeHeader(type) - is HeaderTypes.Step -> buildFlowHeader(type) - is HeaderTypes.Modal -> buildModalHeader(type) - is HeaderTypes.Flex -> buildFlexHeader(type) - } - - if (showDivider) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(Sizes.Stroke.Regular) - .background(MaterialTheme.colorScheme.outline) - .align(Alignment.BottomStart), - ) - } - } - } -} - -@Composable -private fun buildHomeHeader(type: HeaderTypes.Home) { - Text( - text = type.title, - textAlign = TextAlign.Center, - style = typography.titleMedium, - maxLines = 1, - overflow = TextOverflow.Clip, - ) - - Row( - modifier = Modifier - .fillMaxSize() - .padding(Padding.small), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.End, - ) { - SymbolButton( - icon = Symbols.IconSettings, - onClick = type.onSettings, - ) - } -} - -@Composable -private fun buildSubHomeHeader(type: HeaderTypes.SubHome) { - Text( - text = type.title, - textAlign = TextAlign.Center, - style = typography.titleMedium, - maxLines = 1, - overflow = TextOverflow.Clip, - ) -} - -@Composable -private fun buildFlowHeader(type: HeaderTypes.Step) { - Row( - modifier = Modifier - .fillMaxSize() - .padding(Padding.small), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Start, - ) { - SymbolButton( - icon = Symbols.IconArrowBack, - onClick = type.onBack, - ) - } - - Text( - text = type.title, - textAlign = TextAlign.Center, - style = typography.titleMedium, - maxLines = 1, - overflow = TextOverflow.Clip, - ) -} - -@Composable -private fun buildModalHeader(type: HeaderTypes.Modal) { - Row( - modifier = Modifier - .fillMaxSize() - .padding(Padding.small), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Start, - ) { - SymbolButton( - icon = Symbols.IconClose, - onClick = type.onClosed, - ) - } -} - -@Composable -private fun buildFlexHeader(type: HeaderTypes.Flex) { - Row( - modifier = Modifier - .fillMaxSize() - .padding(Padding.small), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Start, - ) { - type.leftShortcuts.forEach { shortcut -> - SymbolButton( - icon = shortcut.icon, - onClick = shortcut.onClick, - ) - } - } - - Text( - text = type.title, - textAlign = TextAlign.Center, - style = typography.titleMedium, - maxLines = 1, - overflow = TextOverflow.Clip, - ) - - Row( - modifier = Modifier - .fillMaxSize() - .padding(Padding.small), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.End, - ) { - type.rightShortcuts.forEach { shortcut -> - SymbolButton( - icon = shortcut.icon, - onClick = shortcut.onClick, - ) - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/zExperiments/Chart.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/zExperiments/Chart.kt deleted file mode 100644 index 6d1e265..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/zExperiments/Chart.kt +++ /dev/null @@ -1,58 +0,0 @@ -package cl.homelogic.platform.designsystem.components.zExperiments - -import androidx.compose.foundation.Canvas -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Path -import androidx.compose.ui.graphics.StrokeCap -import androidx.compose.ui.graphics.StrokeJoin -import androidx.compose.ui.graphics.drawscope.Stroke -import androidx.compose.ui.unit.dp - -@Composable -fun TemperatureGraph( - data: List, - modifier: Modifier = Modifier, - lineColor: Color = Color(0xFF6B7280), -) { - Canvas(modifier = modifier) { - if (data.isEmpty()) return@Canvas - - val path = Path() - val points = Path() - - val xStep = size.width / (data.size - 1) - val yStep = size.height / (data.maxOrNull() ?: 1f) - - // Create smooth curve - path.moveTo(0f, size.height - (data.first() * yStep)) - points.moveTo(0f, size.height - (data.first() * yStep)) - - data.forEachIndexed { index, value -> - if (index == 0) return@forEachIndexed - val x = index * xStep - val y = size.height - (value * yStep) - - // Create smooth curve - val controlX1 = ((index - 1) * xStep + x) / 2f - val controlX2 = controlX1 - val controlY1 = size.height - (data[index - 1] * yStep) - val controlY2 = y - - path.cubicTo(controlX1, controlY1, controlX2, controlY2, x, y) - points.cubicTo(controlX1, controlY1, controlX2, controlY2, x, y) - } - - // Draw the line - drawPath( - path = path, - color = lineColor, - style = Stroke( - width = 2.dp.toPx(), - cap = StrokeCap.Round, - join = StrokeJoin.Round, - ), - ) - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/zExperiments/Greeting.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/zExperiments/Greeting.kt deleted file mode 100644 index 5cd72a1..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/zExperiments/Greeting.kt +++ /dev/null @@ -1,9 +0,0 @@ -package cl.homelogic.platform.designsystem.components.zExperiments - -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable - -@Composable -fun Greeting(name: String) { - Text(text = "Hello, $name!") -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/zExperiments/TemperatureChart.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/zExperiments/TemperatureChart.kt deleted file mode 100644 index 0a1f76f..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/components/zExperiments/TemperatureChart.kt +++ /dev/null @@ -1,95 +0,0 @@ -package cl.homelogic.platform.designsystem.components.zExperiments - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import cl.homelogic.platform.designsystem.foundations.Shapes - -@Composable -fun TemperatureCard( - modifier: Modifier = Modifier, - temperature: Int = 72, - percentage: Float = 2f, - temperatureData: List = emptyList(), -) { - Card( - modifier = modifier - .fillMaxWidth() - .padding(16.dp), - shape = Shapes.RoundCorner.regular, - elevation = CardDefaults.cardElevation(defaultElevation = 4.dp), - ) { - Column( - modifier = Modifier - .padding(24.dp) - .fillMaxWidth(), - ) { - Text( - text = "Temperature", - style = MaterialTheme.typography.titleLarge, - color = MaterialTheme.colorScheme.onSurface, - ) - - Spacer(modifier = Modifier.height(8.dp)) - - Text( - text = temperature.toString(), - style = MaterialTheme.typography.displayLarge, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface, - ) - - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp), - ) { - Text( - text = "Now", - style = MaterialTheme.typography.bodyLarge, - color = Color.Gray, - ) - Text( - text = "+${percentage.toInt()}%", - style = MaterialTheme.typography.bodyLarge, - color = Color(0xFF22C55E), // Green color - ) - } - - Spacer(modifier = Modifier.height(32.dp)) - - TemperatureGraph( - data = temperatureData, - modifier = Modifier - .fillMaxWidth() - .height(120.dp), - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - ) { - Text("9AM", color = Color.Gray) - Text("12PM", color = Color.Gray) - Text("3PM", color = Color.Gray) - Text("6PM", color = Color.Gray) - Text("9PM", color = Color.Gray) - } - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/AccessibilityHelpers.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/AccessibilityHelpers.kt deleted file mode 100644 index 6b5ea3a..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/AccessibilityHelpers.kt +++ /dev/null @@ -1,29 +0,0 @@ -package cl.homelogic.platform.designsystem.extensions - -import androidx.compose.ui.Modifier -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.role -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.semantics.stateDescription -import androidx.compose.ui.semantics.testTag - -data class AccessibilityInfo( - val testTag: String, - val contentDescription: String, - val role: Role, - val stateDescription: String? = null, -) - -fun Modifier.accessibility( - accessibilityInfo: AccessibilityInfo, - mergeDescendants: Boolean = true, -) = this.semantics(mergeDescendants) { - testTag = accessibilityInfo.testTag - contentDescription = accessibilityInfo.contentDescription - role = accessibilityInfo.role - - accessibilityInfo.stateDescription?.let { - stateDescription = it - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ClassHelpers.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ClassHelpers.kt deleted file mode 100644 index 651669b..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ClassHelpers.kt +++ /dev/null @@ -1,13 +0,0 @@ -package cl.homelogic.platform.designsystem.extensions - -import kotlin.contracts.ExperimentalContracts -import kotlin.contracts.contract - -@Suppress("BanInlineOptIn") -@OptIn(ExperimentalContracts::class) -fun requirePrecondition(value: Boolean) { - contract { returns() implies value } - if (!value) { - throw IllegalArgumentException("Shortcuts cannot exceed 3 items") - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ColorHelpers.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ColorHelpers.kt deleted file mode 100644 index a7130a8..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ColorHelpers.kt +++ /dev/null @@ -1,15 +0,0 @@ -package cl.homelogic.platform.designsystem.extensions - -import androidx.compose.ui.graphics.Color -import kotlin.math.roundToInt - -fun Color.toHexString(): String { - val red = (this.red * 255).roundToInt() - val green = (this.green * 255).roundToInt() - val blue = (this.blue * 255).roundToInt() - - return "#" + red.toHexString() + - green.toHexString() + blue.toHexString() -} - -private fun Int.toHexString(): String = this.toString(16).padStart(2, '0').uppercase() diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/FontHelpers.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/FontHelpers.kt deleted file mode 100644 index 2b79399..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/FontHelpers.kt +++ /dev/null @@ -1,31 +0,0 @@ -package cl.homelogic.platform.designsystem.extensions - -import androidx.compose.ui.text.font.FontWeight - -enum class FontWeightTypes( - val weight: Int, -) { - Thin(100), - ExtraLight(200), - Light(300), - Normal(400), - Medium(500), - SemiBold(600), - Bold(700), - ExtraBold(800), - Black(900), -} - -fun FontWeight.toType(): FontWeightTypes = - when (this.weight) { - FontWeightTypes.Thin.weight -> FontWeightTypes.Thin - FontWeightTypes.ExtraLight.weight -> FontWeightTypes.ExtraLight - FontWeightTypes.Light.weight -> FontWeightTypes.Light - FontWeightTypes.Normal.weight -> FontWeightTypes.Normal - FontWeightTypes.Medium.weight -> FontWeightTypes.Medium - FontWeightTypes.SemiBold.weight -> FontWeightTypes.SemiBold - FontWeightTypes.Bold.weight -> FontWeightTypes.Bold - FontWeightTypes.ExtraBold.weight -> FontWeightTypes.ExtraBold - FontWeightTypes.Black.weight -> FontWeightTypes.Black - else -> FontWeightTypes.Normal - } diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/IconHelpers.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/IconHelpers.kt deleted file mode 100644 index 1c0bdfb..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/IconHelpers.kt +++ /dev/null @@ -1,10 +0,0 @@ -package cl.homelogic.platform.designsystem.extensions - -fun String.toUnicode(): String? = - try { - val paddedHex = this.padStart(4, '0') - val codePoint = paddedHex.toInt(16) - codePoint.toChar().toString() - } catch (e: Exception) { - null - } diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ListHelpers.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ListHelpers.kt deleted file mode 100644 index d6722ac..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ListHelpers.kt +++ /dev/null @@ -1,5 +0,0 @@ -package cl.homelogic.platform.designsystem.extensions - -import androidx.compose.runtime.Composable - -fun listOfComposables(vararg composables: @Composable () -> Unit): List<@Composable () -> Unit> = composables.toList() diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ModifierHelpers.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ModifierHelpers.kt deleted file mode 100644 index 8f885bd..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/ModifierHelpers.kt +++ /dev/null @@ -1,57 +0,0 @@ -package cl.homelogic.platform.designsystem.extensions - -import androidx.compose.foundation.Indication -import androidx.compose.foundation.clickable -import androidx.compose.foundation.focusable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.input.pointer.PointerEventPass -import androidx.compose.ui.input.pointer.PointerInputChange -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.semantics.disabled -import androidx.compose.ui.semantics.semantics - -fun Modifier.disable(): Modifier = - this - .alpha(0.3f) - .clickable(enabled = false) {} - .focusable(false) - .semantics { - disabled() - }.pointerInput(Unit) { - awaitPointerEventScope { - while (true) { - val event = awaitPointerEvent(PointerEventPass.Initial) - event.changes.forEach { pointerInputChange: PointerInputChange -> - pointerInputChange.consume() - } - } - } - } - -fun Modifier.clickable(status: Boolean): Modifier = - if (status) { - this - } else { - this.disable() - } - -fun Modifier.intangible(): Modifier = - this - .alpha(0.3f) - -fun Modifier.conditionalClickable( - onClick: (() -> Unit)?, - interactionSource: MutableInteractionSource, - indication: Indication?, -): Modifier = - if (onClick != null) { - this.clickable( - interactionSource = interactionSource, - indication = indication, - onClick = onClick, - ) - } else { - this - } diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/SizeHelpers.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/SizeHelpers.kt deleted file mode 100644 index a72c246..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/extensions/SizeHelpers.kt +++ /dev/null @@ -1,11 +0,0 @@ -package cl.homelogic.platform.designsystem.extensions - -import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.Dp - -@Composable -fun Dp.scaledByFontSize(): Dp { - val fontScale = LocalDensity.current.fontScale - return this * fontScale -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Haptic.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Haptic.kt deleted file mode 100644 index 52a1cfa..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Haptic.kt +++ /dev/null @@ -1,77 +0,0 @@ -package cl.homelogic.platform.designsystem.foundations - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.hapticfeedback.HapticFeedback -import androidx.compose.ui.hapticfeedback.HapticFeedbackType -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow - -enum class FeedbackType { - Confirm, - ContextClick, - GestureEnd, - GestureThresholdActivate, - LongPress, - Reject, - SegmentFrequentTick, - SegmentTick, - TextHandleMove, - ToggleOff, - ToggleOn, - VirtualKey, -} - -class HapticManager( - private val hapticFeedback: HapticFeedback, -) { - private val _hapticEnabled = MutableStateFlow(true) - val status: StateFlow = _hapticEnabled - - fun enable() { - _hapticEnabled.value = true - } - - fun disable() { - _hapticEnabled.value = false - } - - fun performFeedback( - type: FeedbackType, - ) { - if (!_hapticEnabled.value) return - - with(hapticFeedback) { - when (type) { - FeedbackType.Confirm -> performHapticFeedback(HapticFeedbackType.Confirm) - FeedbackType.ContextClick -> performHapticFeedback(HapticFeedbackType.ContextClick) - FeedbackType.GestureEnd -> performHapticFeedback(HapticFeedbackType.GestureEnd) - FeedbackType.GestureThresholdActivate -> performHapticFeedback(HapticFeedbackType.GestureThresholdActivate) - FeedbackType.LongPress -> performHapticFeedback(HapticFeedbackType.LongPress) - FeedbackType.Reject -> performHapticFeedback(HapticFeedbackType.Reject) - FeedbackType.SegmentFrequentTick -> performHapticFeedback(HapticFeedbackType.SegmentFrequentTick) - FeedbackType.SegmentTick -> performHapticFeedback(HapticFeedbackType.SegmentTick) - FeedbackType.TextHandleMove -> performHapticFeedback(HapticFeedbackType.TextHandleMove) - FeedbackType.ToggleOff -> performHapticFeedback(HapticFeedbackType.ToggleOff) - FeedbackType.ToggleOn -> performHapticFeedback(HapticFeedbackType.ToggleOn) - FeedbackType.VirtualKey -> performHapticFeedback(HapticFeedbackType.VirtualKey) - } - } - } -} - -val LocalHapticManager = staticCompositionLocalOf { - error("HapticManager not provided") -} - -@Composable -fun HapticSystem( - hapticFeedback: HapticFeedback, - content: @Composable () -> Unit, -) { - val hapticManager = HapticManager(hapticFeedback) - CompositionLocalProvider(LocalHapticManager provides hapticManager) { - content() - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Palette.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Palette.kt deleted file mode 100644 index 5a1f37d..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Palette.kt +++ /dev/null @@ -1,201 +0,0 @@ -package cl.homelogic.platform.designsystem.foundations - -import androidx.compose.runtime.Immutable -import androidx.compose.ui.graphics.Color - -@Immutable -sealed interface Palette { - val name: String - val color: Color - - sealed class Mono : Palette { - data object At0 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFFFFFFFF) - } - - data object At200 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFFF2F3F5) - } - - data object At250 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFFDBE0E5) - } - - data object At300 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFFC2C3C5) - } - - data object At400 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFF9A9CA0) - } - - data object At500 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFF78828D) - } - - data object At600 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFF637587) - } - - data object At750 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFF48525D) - } - - data object At800 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFF3D4754) - } - - data object At850 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFF38383D) - } - - data object At900 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFF293038) - } - - data object At950 : Mono() { - override val name: String = this.toString() - override val color: Color = Color(0xFF121417) - } - } - - sealed class Brand : Palette { - data object Phoebe : Brand() { - override val name: String = this.toString() - override val color: Color = Color(0xFF10d48e) - } - - data object Joey : Brand() { - override val name: String = this.toString() - override val color: Color = Color(0xFF0fc081) - } - - data object Monica : Brand() { - override val name: String = this.toString() - override val color: Color = Color(0xFF132a3a) - } - - data object Chandler : Brand() { - override val name: String = this.toString() - override val color: Color = Color(0xFF1c3c52) - } - } - - sealed class Sky : Palette { - data object Clear : Sky() { - override val name: String = this.toString() - override val color: Color = Color(0xFF197fe6) - } - - data object Deep : Sky() { - override val name: String = this.toString() - override val color: Color = Color(0xFF005CAC) - } - } - - sealed class Hazard : Palette { - data object Fire : Hazard() { - override val name: String = this.toString() - override val color: Color = Color(0xFFC34836) - } - } - - sealed class Sunset : Palette { - data object Dawn : Sunset() { - override val name: String = this.toString() - override val color: Color = Color(0xFFF49E4E) - } - - data object Sunny : Sunset() { - override val name: String = this.toString() - override val color: Color = Color(0xFFFFA255) - } - - data object Dusk : Sunset() { - override val name: String = this.toString() - override val color: Color = Color(0xFFF5824E) - } - - data object Evening : Sunset() { - override val name: String = this.toString() - override val color: Color = Color(0xFFE07648) - } - - data object Twilight : Sunset() { - override val name: String = this.toString() - override val color: Color = Color(0xFF4E3151) - } - - data object Night : Sunset() { - override val name: String = this.toString() - override val color: Color = Color(0xFF191538) - } - } - - companion object { - fun getMonoColors(): List = - listOf( - Mono.At0, - Mono.At200, - Mono.At250, - Mono.At300, - Mono.At400, - Mono.At500, - Mono.At600, - Mono.At750, - Mono.At800, - Mono.At850, - Mono.At900, - Mono.At950, - ) - - fun getBrandColors(): List = - listOf( - Brand.Phoebe, - Brand.Joey, - Brand.Monica, - Brand.Chandler, - ) - - fun getSkyColors(): List = - listOf( - Sky.Clear, - Sky.Deep, - ) - - fun getHazardColors(): List = - listOf( - Hazard.Fire, - ) - - fun getSunsetColors(): List = - listOf( - Sunset.Dawn, - Sunset.Sunny, - Sunset.Dusk, - Sunset.Evening, - Sunset.Twilight, - Sunset.Night, - ) - - fun getAllColors(): List = - listOf( - getMonoColors(), - getBrandColors(), - getSkyColors(), - getHazardColors(), - getSunsetColors(), - ).flatten() - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Shapes.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Shapes.kt deleted file mode 100644 index a4a4d28..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Shapes.kt +++ /dev/null @@ -1,11 +0,0 @@ -package cl.homelogic.platform.designsystem.foundations - -import androidx.compose.foundation.shape.RoundedCornerShape - -object Shapes { - object RoundCorner { - val small = RoundedCornerShape(Dimens.at6) - val regular = RoundedCornerShape(Dimens.at8) - val big = RoundedCornerShape(Dimens.at12) - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Sizes.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Sizes.kt deleted file mode 100644 index ea58ae1..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Sizes.kt +++ /dev/null @@ -1,130 +0,0 @@ -package cl.homelogic.platform.designsystem.foundations - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.runtime.Immutable -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp - -sealed class Sizes { - object Buttons { - val Small = Dimens.at40 - val Regular = Dimens.at48 - val Big = Dimens.at56 - val Large = Dimens.at72 - } - - object Dots { - val Small = Dimens.at6 - val Regular = Dimens.at8 - val Big = Dimens.at10 - } - - object TextFields { - val Regular = Dimens.at52 - } - - object Images { - val Regular = Dimens.at300 - val Big = Dimens.at350 - } - - object Borders { - val Regular = Dimens.at1 - } - - object Header { - val Regular = Dimens.at72 - } - - object Spacers { - val Regular = Dimens.at8 - val Big = Dimens.at16 - } - - object ScreenInset { - val Bottom = Dimens.at40 - } - - object Shadows { - val Regular = Dimens.at4 - } - - object Stroke { - val Regular = Dimens.at1 - } - - object Containers { - val Small = Dimens.at40 - val Regular = Dimens.at60 - val Big = Dimens.at72 - val Large = Dimens.at120 - val Huge = Dimens.at300 - } -} - -@Immutable -object Padding { - val none = Dimens.at0 - val tiny = Dimens.at4 - val small = Dimens.at8 - val regular = Dimens.at12 - val big = Dimens.at16 - val large = Dimens.at32 - - object Content { - val regular = PaddingValues(vertical = Dimens.at16) - } -} - -@Immutable -object Dimens { - val at0 = 0.dp - val at1 = 1.dp - val at2 = 2.dp - val at4 = 4.dp - val at6 = 6.dp - val at8 = 8.dp - val at10 = 10.dp - val at12 = 12.dp - val at16 = 16.dp - val at20 = 20.dp - val at24 = 24.dp - val at28 = 28.dp - val at32 = 32.dp - val at36 = 36.dp - val at40 = 40.dp - val at44 = 44.dp - val at48 = 48.dp - val at52 = 52.dp - val at56 = 56.dp - val at60 = 60.dp - val at72 = 72.dp - val at120 = 120.dp - val at300 = 300.dp - val at350 = 350.dp -} - -@Immutable -object ScaledDimens { - val at0 = 0.sp - val at2 = 2.sp - val at4 = 4.sp - val at8 = 8.sp - val at12 = 12.sp - val at16 = 16.sp - val at18 = 18.sp - val at20 = 20.sp - val at22 = 22.sp - val at24 = 24.sp - val at26 = 26.sp - val at28 = 28.sp - val at30 = 30.sp - val at32 = 32.sp - val at36 = 36.sp - val at40 = 40.sp - val at44 = 44.sp - val at48 = 48.sp - val at52 = 52.sp - val at56 = 56.sp - val at72 = 72.sp -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Symbols.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Symbols.kt deleted file mode 100644 index 57c0646..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Symbols.kt +++ /dev/null @@ -1,60 +0,0 @@ -package cl.homelogic.platform.designsystem.foundations - -import cl.homelogic.platform.designsystem.foundations.fonts.materialsymbols.getPlatformIcon - -fun Symbols.unicode(): String = - this.codePoint[0] - .code - .toString(16) - .padStart(4, '0') - -// Get codepoints from: https://fonts.google.com/icons -sealed class Symbols( - val codePoint: String, -) { - data object IconSettings : Symbols("\ue8b8") - - data object IconArrowBack : Symbols(getPlatformIcon("\ue5c4", "\ue5e0")) - - data object IconClose : Symbols("\ue5cd") - - data object IconTextField : Symbols("\ue9f1") - - data object IconButtons : Symbols("\ue72f") - - data object IconHeader : Symbols("\uf384") - - data object IconSwitchCard : Symbols("\ue1f4") - - data object IconFonts : Symbols("\ue262") - - data object IconShortcut : Symbols("\ue7e1") - - data object IconSymbols : Symbols("\uf7f7") - - data object IconHeadline : Symbols("\ue23c") - - data object IconHeadlines : Symbols("\ue91a") - - data object IconTypography : Symbols("\ueb94") - - data object IconTwoColumns : Symbols("\uf847") - - data object IconGlyph : Symbols("\ue574") - - data object IconColors : Symbols("\ue40a") - - data object IconThemes : Symbols("\ue997") - - data object IconShapes : Symbols("\ue602") - - data object IconDimensions : Symbols("\ue41c") - - data object IconIllustrations : Symbols("\ue3f4") - - data object IconDarkMode : Symbols("\ue51c") - - data object IconSearch : Symbols("\ue8b6") - - data object IconPlayCircle : Symbols("\ue1c4") -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Themes.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Themes.kt deleted file mode 100644 index 381309b..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Themes.kt +++ /dev/null @@ -1,51 +0,0 @@ -package cl.homelogic.platform.designsystem.foundations - -import cl.homelogic.platform.designsystem.themes.BaseTheme -import cl.homelogic.platform.designsystem.themes.ColorPair - -enum class Themes( - val definition: BaseTheme, -) { - ClassicVibes(Classic), - MintVibes(Mint), -} - -private object Classic : BaseTheme() { - override val primary = ColorPair(Palette.Mono.At950, Palette.Mono.At0) - override val primaryContainer = ColorPair(Palette.Mono.At0, Palette.Mono.At950) - override val onPrimary = ColorPair(Palette.Mono.At950, Palette.Mono.At0) - override val onPrimaryContainer = ColorPair(Palette.Mono.At0, Palette.Mono.At950) - override val secondary = ColorPair(Palette.Mono.At950, Palette.Mono.At0) - override val secondaryContainer = ColorPair(Palette.Mono.At250, Palette.Mono.At900) - override val tertiary = ColorPair(Palette.Sky.Clear, Palette.Sky.Deep) - override val tertiaryContainer = ColorPair(Palette.Mono.At250, Palette.Mono.At900) - override val onTertiary = ColorPair(Palette.Mono.At0, Palette.Mono.At0) - override val surfaceContainer = ColorPair(Palette.Mono.At0, Palette.Mono.At950) - override val error = ColorPair(Palette.Hazard.Fire, Palette.Hazard.Fire) - override val surface = ColorPair(Palette.Mono.At0, Palette.Mono.At950) - override val surfaceVariant = ColorPair(Palette.Mono.At200, Palette.Mono.At900) - override val onSurface = ColorPair(Palette.Mono.At950, Palette.Mono.At0) - override val onSurfaceVariant = ColorPair(Palette.Mono.At600, Palette.Mono.At0) - override val background = ColorPair(Palette.Mono.At0, Palette.Mono.At950) - override val outline = ColorPair(Palette.Mono.At250, Palette.Mono.At850) -} - -private object Mint : BaseTheme() { - override val primary = ColorPair(Palette.Brand.Monica, Palette.Brand.Joey) - override val primaryContainer = ColorPair(Palette.Mono.At0, Palette.Brand.Joey) - override val onPrimary = ColorPair(Palette.Mono.At950, Palette.Mono.At0) - override val onPrimaryContainer = ColorPair(Palette.Mono.At0, Palette.Mono.At950) - override val secondary = ColorPair(Palette.Mono.At950, Palette.Mono.At0) - override val secondaryContainer = ColorPair(Palette.Mono.At250, Palette.Mono.At900) - override val tertiary = ColorPair(Palette.Brand.Phoebe, Palette.Brand.Joey) - override val tertiaryContainer = ColorPair(Palette.Mono.At250, Palette.Mono.At900) - override val onTertiary = ColorPair(Palette.Mono.At0, Palette.Mono.At0) - override val surfaceContainer = ColorPair(Palette.Mono.At0, Palette.Mono.At950) - override val error = ColorPair(Palette.Hazard.Fire, Palette.Hazard.Fire) - override val surface = ColorPair(Palette.Mono.At0, Palette.Mono.At950) - override val surfaceVariant = ColorPair(Palette.Mono.At200, Palette.Mono.At850) - override val onSurface = ColorPair(Palette.Mono.At950, Palette.Mono.At0) - override val onSurfaceVariant = ColorPair(Palette.Mono.At600, Palette.Mono.At0) - override val background = ColorPair(Palette.Mono.At0, Palette.Mono.At950) - override val outline = ColorPair(Palette.Mono.At250, Palette.Mono.At850) -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Typography.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Typography.kt deleted file mode 100644 index a6af80c..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/Typography.kt +++ /dev/null @@ -1,77 +0,0 @@ -package cl.homelogic.platform.designsystem.foundations - -import androidx.compose.material3.Typography -import androidx.compose.runtime.Composable -import androidx.compose.ui.text.font.FontWeight -import cl.homelogic.platform.designsystem.foundations.fonts.manrope.ManropeFontFamily -import cl.homelogic.platform.designsystem.foundations.fonts.materialsymbols.SymbolsOutlinedFontFamily - -@Composable -fun ManropeTypography() = - Typography().run { - val fontFamily = ManropeFontFamily() - copy( - displayLarge = displayLarge.copy( - fontFamily = SymbolsOutlinedFontFamily(), - ), - displayMedium = displayMedium.copy( - fontSize = ScaledDimens.at32, - fontFamily = SymbolsOutlinedFontFamily(), - fontWeight = FontWeight.Light, - ), - displaySmall = displaySmall.copy( - fontSize = ScaledDimens.at24, - fontFamily = SymbolsOutlinedFontFamily(), - fontWeight = FontWeight.Light, - lineHeight = ScaledDimens.at30, - ), - headlineLarge = headlineLarge.copy( - fontFamily = fontFamily, - fontSize = ScaledDimens.at26, - fontWeight = FontWeight.ExtraBold, - lineHeight = ScaledDimens.at48, - ), - headlineMedium = headlineMedium.copy( - fontFamily = fontFamily, - fontSize = ScaledDimens.at22, - fontWeight = FontWeight.Bold, - lineHeight = ScaledDimens.at28, - ), - headlineSmall = headlineSmall.copy( - fontFamily = fontFamily, - ), - titleLarge = titleLarge.copy( - fontFamily = fontFamily, - ), - titleMedium = titleMedium.copy( - fontFamily = fontFamily, - fontSize = ScaledDimens.at18, - fontWeight = FontWeight.ExtraBold, - lineHeight = ScaledDimens.at22, - ), - titleSmall = titleSmall.copy( - fontFamily = fontFamily, - ), - bodyLarge = bodyMedium.copy( - fontFamily = fontFamily, - fontWeight = FontWeight.ExtraBold, - ), - bodyMedium = bodyMedium.copy( - fontFamily = fontFamily, - fontWeight = FontWeight.Medium, - ), - bodySmall = bodySmall.copy( - fontFamily = fontFamily, - ), - labelLarge = labelLarge.copy( - fontFamily = fontFamily, - fontWeight = FontWeight.ExtraBold, - ), - labelMedium = labelMedium.copy( - fontFamily = fontFamily, - ), - labelSmall = labelSmall.copy( - fontFamily = fontFamily, - ), - ) - } diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/fonts/manrope/ManropeFontFamily.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/fonts/manrope/ManropeFontFamily.kt deleted file mode 100644 index eddba56..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/fonts/manrope/ManropeFontFamily.kt +++ /dev/null @@ -1,26 +0,0 @@ -package cl.homelogic.platform.designsystem.foundations.fonts.manrope - -import androidx.compose.runtime.Composable -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import cl.homelogic.platform.designsystem.resources.Manrope_Bold -import cl.homelogic.platform.designsystem.resources.Manrope_ExtraBold -import cl.homelogic.platform.designsystem.resources.Manrope_ExtraLight -import cl.homelogic.platform.designsystem.resources.Manrope_Light -import cl.homelogic.platform.designsystem.resources.Manrope_Medium -import cl.homelogic.platform.designsystem.resources.Manrope_Regular -import cl.homelogic.platform.designsystem.resources.Manrope_SemiBold -import cl.homelogic.platform.designsystem.resources.Res -import org.jetbrains.compose.resources.Font - -@Composable -fun ManropeFontFamily() = - FontFamily( - Font(Res.font.Manrope_ExtraLight, weight = FontWeight.ExtraLight), - Font(Res.font.Manrope_Light, weight = FontWeight.Light), - Font(Res.font.Manrope_Regular, weight = FontWeight.Normal), - Font(Res.font.Manrope_Medium, weight = FontWeight.Medium), - Font(Res.font.Manrope_SemiBold, weight = FontWeight.SemiBold), - Font(Res.font.Manrope_Bold, weight = FontWeight.Bold), - Font(Res.font.Manrope_ExtraBold, weight = FontWeight.ExtraBold), - ) diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/fonts/materialsymbols/MaterialSymbolsFontFamily.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/fonts/materialsymbols/MaterialSymbolsFontFamily.kt deleted file mode 100644 index 16646ff..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/foundations/fonts/materialsymbols/MaterialSymbolsFontFamily.kt +++ /dev/null @@ -1,119 +0,0 @@ -package cl.homelogic.platform.designsystem.foundations.fonts.materialsymbols - -import androidx.compose.runtime.Composable -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import cl.homelogic.platform.common.Platform -import cl.homelogic.platform.common.PlatformTypes -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_Bold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_ExtraLight -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_Filled_Bold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_Filled_ExtraLight -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_Filled_Light -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_Filled_Medium -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_Filled_Regular -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_Filled_SemiBold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_Light -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_Medium -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_Regular -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsOutlined_SemiBold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_Bold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_ExtraLight -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_Filled_Bold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_Filled_ExtraLight -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_Filled_Light -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_Filled_Medium -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_Filled_Regular -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_Filled_SemiBold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_Light -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_Medium -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_Regular -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsRounded_SemiBold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_Bold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_ExtraLight -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_Filled_Bold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_Filled_ExtraLight -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_Filled_Light -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_Filled_Medium -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_Filled_Regular -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_Filled_SemiBold -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_Light -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_Medium -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_Regular -import cl.homelogic.platform.designsystem.resources.MaterialSymbolsSharp_SemiBold -import cl.homelogic.platform.designsystem.resources.Res -import org.jetbrains.compose.resources.Font - -@Composable -internal fun SymbolsSharpFontFamily() = - FontFamily( - Font(Res.font.MaterialSymbolsSharp_ExtraLight, weight = FontWeight.ExtraLight), - Font(Res.font.MaterialSymbolsSharp_Light, weight = FontWeight.Light), - Font(Res.font.MaterialSymbolsSharp_Regular, weight = FontWeight.Normal), - Font(Res.font.MaterialSymbolsSharp_Medium, weight = FontWeight.Medium), - Font(Res.font.MaterialSymbolsSharp_SemiBold, weight = FontWeight.SemiBold), - Font(Res.font.MaterialSymbolsSharp_Bold, weight = FontWeight.Bold), - ) - -@Composable -internal fun SymbolsSharpFilledFontFamily() = - FontFamily( - Font(Res.font.MaterialSymbolsSharp_Filled_ExtraLight, weight = FontWeight.ExtraLight), - Font(Res.font.MaterialSymbolsSharp_Filled_Light, weight = FontWeight.Light), - Font(Res.font.MaterialSymbolsSharp_Filled_Regular, weight = FontWeight.Normal), - Font(Res.font.MaterialSymbolsSharp_Filled_Medium, weight = FontWeight.Medium), - Font(Res.font.MaterialSymbolsSharp_Filled_SemiBold, weight = FontWeight.SemiBold), - Font(Res.font.MaterialSymbolsSharp_Filled_Bold, weight = FontWeight.Bold), - ) - -@Composable -internal fun SymbolsRoundedFontFamily() = - FontFamily( - Font(Res.font.MaterialSymbolsRounded_ExtraLight, weight = FontWeight.ExtraLight), - Font(Res.font.MaterialSymbolsRounded_Light, weight = FontWeight.Light), - Font(Res.font.MaterialSymbolsRounded_Regular, weight = FontWeight.Normal), - Font(Res.font.MaterialSymbolsRounded_Medium, weight = FontWeight.Medium), - Font(Res.font.MaterialSymbolsRounded_SemiBold, weight = FontWeight.SemiBold), - Font(Res.font.MaterialSymbolsRounded_Bold, weight = FontWeight.Bold), - ) - -@Composable -internal fun SymbolsRoundedFilledFontFamily() = - FontFamily( - Font(Res.font.MaterialSymbolsRounded_Filled_ExtraLight, weight = FontWeight.ExtraLight), - Font(Res.font.MaterialSymbolsRounded_Filled_Light, weight = FontWeight.Light), - Font(Res.font.MaterialSymbolsRounded_Filled_Regular, weight = FontWeight.Normal), - Font(Res.font.MaterialSymbolsRounded_Filled_Medium, weight = FontWeight.Medium), - Font(Res.font.MaterialSymbolsRounded_Filled_SemiBold, weight = FontWeight.SemiBold), - Font(Res.font.MaterialSymbolsRounded_Filled_Bold, weight = FontWeight.Bold), - ) - -@Composable -internal fun SymbolsOutlinedFontFamily() = - FontFamily( - Font(Res.font.MaterialSymbolsOutlined_ExtraLight, weight = FontWeight.ExtraLight), - Font(Res.font.MaterialSymbolsOutlined_Light, weight = FontWeight.Light), - Font(Res.font.MaterialSymbolsOutlined_Regular, weight = FontWeight.Normal), - Font(Res.font.MaterialSymbolsOutlined_Medium, weight = FontWeight.Medium), - Font(Res.font.MaterialSymbolsOutlined_SemiBold, weight = FontWeight.SemiBold), - Font(Res.font.MaterialSymbolsOutlined_Bold, weight = FontWeight.Bold), - ) - -@Composable -internal fun SymbolsOutlinedFilledFontFamily() = - FontFamily( - Font(Res.font.MaterialSymbolsOutlined_Filled_ExtraLight, weight = FontWeight.ExtraLight), - Font(Res.font.MaterialSymbolsOutlined_Filled_Light, weight = FontWeight.Light), - Font(Res.font.MaterialSymbolsOutlined_Filled_Regular, weight = FontWeight.Normal), - Font(Res.font.MaterialSymbolsOutlined_Filled_Medium, weight = FontWeight.Medium), - Font(Res.font.MaterialSymbolsOutlined_Filled_SemiBold, weight = FontWeight.SemiBold), - Font(Res.font.MaterialSymbolsOutlined_Filled_Bold, weight = FontWeight.Bold), - ) - -internal fun getPlatformIcon( - android: String, - ios: String, -) = when (Platform.getType()) { - PlatformTypes.IOS -> ios - PlatformTypes.Android -> android -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/BaseTheme.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/BaseTheme.kt deleted file mode 100644 index 14557c8..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/BaseTheme.kt +++ /dev/null @@ -1,73 +0,0 @@ -package cl.homelogic.platform.designsystem.themes - -import androidx.compose.material3.ColorScheme -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.lightColorScheme -import cl.homelogic.platform.designsystem.foundations.Palette - -data class ColorPair( - val light: Palette, - val dark: Palette, -) - -abstract class BaseTheme { - abstract val primary: ColorPair - abstract val primaryContainer: ColorPair - abstract val onPrimary: ColorPair - abstract val onPrimaryContainer: ColorPair - abstract val secondary: ColorPair - abstract val secondaryContainer: ColorPair - abstract val tertiary: ColorPair - abstract val tertiaryContainer: ColorPair - abstract val onTertiary: ColorPair - abstract val surfaceContainer: ColorPair - abstract val error: ColorPair - abstract val surface: ColorPair - abstract val surfaceVariant: ColorPair - abstract val onSurface: ColorPair - abstract val onSurfaceVariant: ColorPair - abstract val background: ColorPair - abstract val outline: ColorPair - - val lightVariant: ColorScheme - get() = lightColorScheme( - primary = primary.light.color, - primaryContainer = primaryContainer.light.color, - onPrimary = onPrimary.light.color, - onPrimaryContainer = onPrimaryContainer.light.color, - secondary = secondary.light.color, - secondaryContainer = secondaryContainer.light.color, - tertiary = tertiary.light.color, - tertiaryContainer = tertiaryContainer.light.color, - onTertiary = onTertiary.light.color, - surfaceContainer = surfaceContainer.light.color, - error = error.light.color, - surface = surface.light.color, - surfaceVariant = surfaceVariant.light.color, - onSurface = onSurface.light.color, - onSurfaceVariant = onSurfaceVariant.light.color, - background = background.light.color, - outline = outline.light.color, - ) - - val darkVariant: ColorScheme - get() = darkColorScheme( - primary = primary.dark.color, - primaryContainer = primaryContainer.dark.color, - onPrimary = onPrimary.dark.color, - onPrimaryContainer = onPrimaryContainer.dark.color, - secondary = secondary.dark.color, - secondaryContainer = secondaryContainer.dark.color, - tertiary = tertiary.dark.color, - tertiaryContainer = tertiaryContainer.dark.color, - onTertiary = onTertiary.dark.color, - surfaceContainer = surfaceContainer.dark.color, - error = error.dark.color, - surface = surface.dark.color, - surfaceVariant = surfaceVariant.dark.color, - onSurface = onSurface.dark.color, - onSurfaceVariant = onSurfaceVariant.dark.color, - background = background.dark.color, - outline = outline.dark.color, - ) -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/DesignSystem.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/DesignSystem.kt deleted file mode 100644 index b7b5d61..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/DesignSystem.kt +++ /dev/null @@ -1,41 +0,0 @@ -package cl.homelogic.platform.designsystem.themes - -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.platform.LocalHapticFeedback -import cl.homelogic.platform.designsystem.foundations.HapticSystem -import cl.homelogic.platform.designsystem.foundations.ManropeTypography - -val LocalDesignSystem = staticCompositionLocalOf { - error("DesignSystemManager not provided") -} - -@Composable -fun DesignSystem( - designSystemManager: DesignSystemManager, - content: @Composable () -> Unit, -) { - val state = designSystemManager.state.collectAsState().value - - HapticSystem( - hapticFeedback = LocalHapticFeedback.current, - ) { - MaterialTheme( - colorScheme = when (state.darkMode) { - DarkModeState.Disabled -> state.theme.definition.lightVariant - DarkModeState.Enabled -> state.theme.definition.darkVariant - DarkModeState.Oled -> state.theme.definition.darkVariant - }, - typography = ManropeTypography(), - ) { - CompositionLocalProvider( - LocalDesignSystem provides designSystemManager, - ) { - content() - } - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/DesignSystemManager.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/DesignSystemManager.kt deleted file mode 100644 index 9f3b75a..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/DesignSystemManager.kt +++ /dev/null @@ -1,63 +0,0 @@ -package cl.homelogic.platform.designsystem.themes - -import cl.homelogic.platform.common.logging.Trace -import cl.homelogic.platform.common.logging.TreeRoots -import cl.homelogic.platform.designsystem.foundations.Themes -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.launch - -data class DesignSystemState( - val theme: Themes, - val darkMode: DarkModeState, -) - -enum class DarkModeState { - Disabled, - Enabled, - Oled, -} - -class DesignSystemManager( - theme: Themes, - darkMode: DarkModeState, -) { - private val _coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) - - private val _statusBarManager = StatusBarManager() - - private val _state = - MutableStateFlow(DesignSystemState(theme, darkMode)) - val state: StateFlow = _state - - init { - Trace.d(TreeRoots.DesignSystem, "Initializing Design System") - } - - fun setTheme(theme: Themes) { - Trace.i(TreeRoots.DesignSystem, "Changing theme state to: ${theme.name}") - _coroutineScope.launch { - _state.emit(_state.value.copy(theme = theme)) - } - } - - fun getTheme(): Themes = _state.value.theme - - fun getDarkMode() = _state.value.darkMode - - fun setDarkMode(darkMode: DarkModeState) { - Trace.i(TreeRoots.DesignSystem, "Changing dark mode state to: ${darkMode.name}") - when (darkMode) { - DarkModeState.Disabled -> _statusBarManager.lightMode() - DarkModeState.Enabled -> _statusBarManager.darkMode() - DarkModeState.Oled -> _statusBarManager.darkMode() - } - - _coroutineScope.launch { - _state.emit(_state.value.copy(darkMode = darkMode)) - } - } -} diff --git a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/StatusBarManager.kt b/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/StatusBarManager.kt deleted file mode 100644 index 3c4db41..0000000 --- a/core/designsystem/src/commonMain/kotlin/cl/homelogic/platform/designsystem/themes/StatusBarManager.kt +++ /dev/null @@ -1,10 +0,0 @@ -package cl.homelogic.platform.designsystem.themes - -interface IStatusBarManager { - fun lightMode() - - fun darkMode() -} - -@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") -expect class StatusBarManager() : IStatusBarManager diff --git a/core/designsystem/src/iosMain/kotlin/cl/homelogic/platform/designsystem/themes/StatusBarManager.ios.kt b/core/designsystem/src/iosMain/kotlin/cl/homelogic/platform/designsystem/themes/StatusBarManager.ios.kt deleted file mode 100644 index 3eb1d77..0000000 --- a/core/designsystem/src/iosMain/kotlin/cl/homelogic/platform/designsystem/themes/StatusBarManager.ios.kt +++ /dev/null @@ -1,27 +0,0 @@ -package cl.homelogic.platform.designsystem.themes - -import cl.homelogic.platform.common.logging.Trace -import cl.homelogic.platform.common.logging.TreeRoots -import platform.UIKit.UIApplication -import platform.UIKit.UIStatusBarStyleDarkContent -import platform.UIKit.UIStatusBarStyleLightContent -import platform.UIKit.setStatusBarStyle - -@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") -actual class StatusBarManager : IStatusBarManager { - override fun lightMode() { - Trace.d(TreeRoots.DesignSystem, "iOS - requesting light status bar") - UIApplication.sharedApplication.setStatusBarStyle( - UIStatusBarStyleLightContent, - animated = true, - ) - } - - override fun darkMode() { - Trace.d(TreeRoots.DesignSystem, "iOS - requesting dark status bar") - UIApplication.sharedApplication.setStatusBarStyle( - UIStatusBarStyleDarkContent, - animated = true, - ) - } -} diff --git a/core/navigation/build.gradle.kts b/core/navigation/build.gradle.kts deleted file mode 100644 index 050927c..0000000 --- a/core/navigation/build.gradle.kts +++ /dev/null @@ -1,26 +0,0 @@ -group = "dev.carlosmartino.navigation" - -plugins { - alias(libs.plugins.kotlinDevKit) - alias(libs.plugins.composeDevKit) -} - -kotlin { - sourceSets { - commonMain.dependencies { - api(libs.compose.multiplatform.navigation) - implementation(projects.core.common) - implementation(projects.core.designsystem) - } - - androidMain.dependencies { - api(libs.androidx.compose.navigation) - } - } -} - -compose.resources { - publicResClass = true - packageOfResClass = "dev.carlosmartino.navigation.resources" - generateResClass = always -} diff --git a/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationExtensions.kt b/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationExtensions.kt deleted file mode 100644 index ec5dd75..0000000 --- a/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationExtensions.kt +++ /dev/null @@ -1,60 +0,0 @@ -package cl.homelogic.platform.navigation - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.navigation.NavDeepLink -import androidx.navigation.NavGraphBuilder -import androidx.navigation.compose.composable -import androidx.navigation.toRoute -import cl.homelogic.platform.common.logging.Trace -import cl.homelogic.platform.common.logging.TreeRoots - -inline fun NavGraphBuilder.createRoute( - transition: NavigationTransition = NavigationTransition.FLOW, - deepLinks: List = listOf(), - crossinline content: @Composable (T) -> Unit, -) { - composable( -// enterTransition = { -// when (transition) { -// NavigationTransition.FLOW -> slideInHorizontally() -// NavigationTransition.SINGLE -> NavigationAnimations.verticalEnter -// } -// }, -// exitTransition = { -// when (transition) { -// NavigationTransition.FLOW -> slideOutHorizontally() -// NavigationTransition.SINGLE -> NavigationAnimations.verticalExit -// } -// }, -// popEnterTransition = { -// when (transition) { -// NavigationTransition.FLOW -> NavigationAnimations.horizontalPopEnter -// NavigationTransition.SINGLE -> NavigationAnimations.verticalPopEnter -// } -// }, -// popExitTransition = { -// when (transition) { -// NavigationTransition.FLOW -> slideOutHorizontally() -// NavigationTransition.SINGLE -> NavigationAnimations.verticalPopExit -// } -// }, - deepLinks = deepLinks, - ) { backStackEntry -> - val route: T = remember { backStackEntry.toRoute() } - val isFirstComposition = remember { true } - if (isFirstComposition) { - Trace.i( - TreeRoots.Navigation, - "Route created: ${ - route::class - .qualifiedName - ?.split(".") - ?.takeLast(2) - ?.joinToString(".") ?: route::class.simpleName - }", - ) - content(route) - } - } -} diff --git a/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationManager.kt b/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationManager.kt deleted file mode 100644 index 330a623..0000000 --- a/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationManager.kt +++ /dev/null @@ -1,101 +0,0 @@ -package cl.homelogic.platform.navigation - -import androidx.navigation.NavUri -import cl.homelogic.platform.common.logging.Trace -import cl.homelogic.platform.common.logging.TreeRoots -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlin.time.Clock -import kotlin.time.Duration.Companion.milliseconds -import kotlin.time.Instant - -sealed class NavigationCommand { - data class Route( - val destination: NavigationDestination, - ) : NavigationCommand() - - data class DeepLink( - val uri: NavUri, - ) : NavigationCommand() - - data object PopBack : NavigationCommand() - - data class PopUpTo( - val destination: NavigationDestination, - val inclusive: Boolean = false, - ) : NavigationCommand() -} - -class NavigationManager { - private val _navigationEvents = MutableSharedFlow() - internal val navigationEvents = _navigationEvents.asSharedFlow() - - private val throttleWindow = 100.milliseconds - private var lastNavigationTime: Instant = Instant.DISTANT_PAST - - suspend fun navigate(destination: NavigationDestination) { - if (shouldThrottleNavigation()) { - Trace.d(TreeRoots.Navigation, "Navigation throttled: ${destination::class}") - return - } - - Trace.d( - TreeRoots.Navigation, - "Navigating to: ${ - destination::class - .qualifiedName - ?.split(".") - ?.takeLast(2) - ?.joinToString(".") ?: destination::class.simpleName - }", - ) - updateLastNavigationTime() - _navigationEvents.emit(NavigationCommand.Route(destination)) - } - - suspend fun navigate(deepLink: NavUri) { - if (shouldThrottleNavigation()) { - Trace.d(TreeRoots.Navigation, "DeepLink navigation throttled for: $deepLink") - return - } - - Trace.d(TreeRoots.Navigation, "Navigating to deeplink: $deepLink") - updateLastNavigationTime() - _navigationEvents.emit(NavigationCommand.DeepLink(deepLink)) - } - - suspend fun popBackStack() { - if (shouldThrottleNavigation()) { - Trace.d(TreeRoots.Navigation, "PopBackStack throttled") - return - } - - Trace.d(TreeRoots.Navigation, "PopBackStack triggered") - updateLastNavigationTime() - _navigationEvents.emit(NavigationCommand.PopBack) - } - - suspend fun popUpTo( - destination: NavigationDestination, - inclusive: Boolean, - ) { - if (shouldThrottleNavigation()) { - Trace.d(TreeRoots.Navigation, "PopBackStack throttled") - return - } - - Trace.d(TreeRoots.Navigation, "PopBackStack triggered") - updateLastNavigationTime() - _navigationEvents.emit(NavigationCommand.PopUpTo(destination, inclusive)) - } - - private fun shouldThrottleNavigation(): Boolean { - val currentTime = Clock.System.now() - val lastNavigation = lastNavigationTime - return (currentTime - lastNavigation) < throttleWindow - } - - private fun updateLastNavigationTime() { - lastNavigationTime = Clock.System.now() - } -} diff --git a/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationStructure.kt b/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationStructure.kt deleted file mode 100644 index fe12d5e..0000000 --- a/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationStructure.kt +++ /dev/null @@ -1,13 +0,0 @@ -package cl.homelogic.platform.navigation - -import androidx.navigation.NavGraphBuilder -import androidx.navigation.NavHostController - -interface NavigationModule { - fun navigationGraph( - navGraphBuilder: NavGraphBuilder, - navController: NavHostController, - ) -} - -interface NavigationDestination diff --git a/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationSystem.kt b/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationSystem.kt deleted file mode 100644 index caf30e8..0000000 --- a/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationSystem.kt +++ /dev/null @@ -1,65 +0,0 @@ -package cl.homelogic.platform.navigation - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.asPaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.ui.Modifier -import androidx.navigation.NavUri -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.rememberNavController -import com.moriatsushi.insetsx.statusBars -import kotlinx.coroutines.flow.MutableSharedFlow - -@Composable -fun NavigationSystem( - navigationManager: NavigationManager, - deeplinkStream: MutableSharedFlow? = null, - startDestination: NavigationDestination, - navigationModules: List, -) { - val navController = rememberNavController() - - LaunchedEffect(navController) { - deeplinkStream?.collect { - navController.navigate(NavUri(it)) - } - } - - LaunchedEffect(navController) { - navigationManager.navigationEvents.collect { command -> - when (command) { - is NavigationCommand.Route -> navController.navigate(command.destination) - is NavigationCommand.DeepLink -> navController.navigate(command.uri) - is NavigationCommand.PopBack -> navController.popBackStack() - is NavigationCommand.PopUpTo -> navController.popBackStack( - command.destination, - command.inclusive, - ) - } - } - } - - Box( - modifier = Modifier - .background(MaterialTheme.colorScheme.background) - .fillMaxSize() - .padding( - top = WindowInsets.statusBars.asPaddingValues().calculateTopPadding(), - ), - ) { - NavHost( - navController = navController, - startDestination = startDestination, - ) { - navigationModules.forEach { module -> - module.navigationGraph(this, navController) - } - } - } -} diff --git a/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationTransition.kt b/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationTransition.kt deleted file mode 100644 index 53cc0db..0000000 --- a/core/navigation/src/commonMain/kotlin/cl/homelogic/platform/navigation/NavigationTransition.kt +++ /dev/null @@ -1,79 +0,0 @@ -package cl.homelogic.platform.navigation - -import androidx.compose.animation.EnterTransition -import androidx.compose.animation.ExitTransition -import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.scaleIn -import androidx.compose.animation.scaleOut -import androidx.compose.animation.slideInHorizontally -import androidx.compose.animation.slideInVertically -import androidx.compose.animation.slideOutHorizontally -import androidx.compose.animation.slideOutVertically - -enum class NavigationTransition { - FLOW, - SINGLE, -} - -object NavigationAnimations { - private const val ANIMATION_DURATION = 200 - private const val OVERLAY_SCALE_REDUCED = 0.95f - private const val OVERLAY_OPACITY = 0.3f - - val horizontalEnter: EnterTransition = slideInHorizontally( - initialOffsetX = { fullWidth -> fullWidth }, - animationSpec = tween(ANIMATION_DURATION), - ) + fadeIn( - animationSpec = tween(ANIMATION_DURATION), - ) - - val horizontalExit: ExitTransition = fadeOut( - animationSpec = tween(ANIMATION_DURATION), - ) + scaleOut( - targetScale = OVERLAY_SCALE_REDUCED, - animationSpec = tween(ANIMATION_DURATION), - ) - - val horizontalPopEnter: EnterTransition = fadeIn( - animationSpec = tween(ANIMATION_DURATION), - ) + scaleIn( - initialScale = OVERLAY_SCALE_REDUCED, - animationSpec = tween(ANIMATION_DURATION), - ) - - val horizontalPopExit: ExitTransition = slideOutHorizontally( - targetOffsetX = { fullWidth -> fullWidth }, - animationSpec = tween(ANIMATION_DURATION), - ) + fadeOut( - animationSpec = tween(ANIMATION_DURATION), - ) - - // For vertical modal transitions - val verticalEnter: EnterTransition = slideInVertically( - initialOffsetY = { fullHeight -> fullHeight }, - animationSpec = tween(ANIMATION_DURATION), - ) - - val verticalExit: ExitTransition = fadeOut( - targetAlpha = OVERLAY_OPACITY, - animationSpec = tween(ANIMATION_DURATION), - ) + scaleOut( - targetScale = OVERLAY_SCALE_REDUCED, - animationSpec = tween(ANIMATION_DURATION), - ) - - val verticalPopEnter: EnterTransition = fadeIn( - initialAlpha = OVERLAY_OPACITY, - animationSpec = tween(ANIMATION_DURATION), - ) + scaleIn( - initialScale = OVERLAY_SCALE_REDUCED, - animationSpec = tween(ANIMATION_DURATION), - ) - - val verticalPopExit: ExitTransition = slideOutVertically( - targetOffsetY = { fullHeight -> fullHeight }, - animationSpec = tween(ANIMATION_DURATION), - ) -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 0172bf8..bfb6a1a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -30,6 +30,6 @@ dependencyResolutionManagement { } include(":app:composeApp") -include(":core:designsystem") -include(":core:common") -include(":core:navigation") +include(":bedrock:designsystem") +include(":bedrock:common") +include(":bedrock:navigation")