Created
January 19, 2026 13:32
-
-
Save ArthurKun21/51f29b58f8aaeef67f27165fcf12e075 to your computer and use it in GitHub Desktop.
Compose Component Resources String helper to make it easier to reuse the string resource for both composable and non-composable environments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import androidx.compose.runtime.Composable | |
| import org.jetbrains.compose.resources.PluralStringResource | |
| import org.jetbrains.compose.resources.StringResource | |
| import org.jetbrains.compose.resources.getPluralString | |
| import org.jetbrains.compose.resources.getString | |
| import org.jetbrains.compose.resources.pluralStringResource | |
| import org.jetbrains.compose.resources.stringResource | |
| /** | |
| * A sealed interface that abstracts compose component string resources, allowing them to be passed | |
| * as data and resolved later in either a [Composable] or a non-composable context. | |
| * | |
| * This utility provides a unified way to handle different types of resource resolutions, | |
| * such as standard strings with arguments or pluralized forms, while maintaining | |
| * compatibility with Compose Multiplatform resource loading. | |
| * | |
| * Use the [plus] operator to combine multiple ComposeString instances: | |
| * ``` | |
| * val combined = ComposeString.Strings(Res.string.hello) + ComposeString.Strings(Res.string.world) | |
| * ``` | |
| */ | |
| sealed interface ComposeString { | |
| /** | |
| * Resolves the localized string in a non-composable context. | |
| * | |
| * This is a suspending function as it may perform asynchronous resource loading. | |
| * | |
| * @return The resolved localized string. | |
| */ | |
| suspend fun asString(): String | |
| /** | |
| * Resolves the localized string within a Compose [Composable] context. | |
| * | |
| * This function utilizes the current composition's resources to return the formatted | |
| * string, automatically reacting to configuration changes (like language or orientation). | |
| * | |
| * @return The resolved and formatted localized [String]. | |
| */ | |
| @Composable | |
| fun asStringComposable(): String | |
| /** | |
| * Combines this ComposeString with another ComposeString. | |
| * | |
| * @param other The ComposeString to append to this one. | |
| * @return A new Combined ComposeString that represents both strings concatenated. | |
| */ | |
| operator fun plus(other: ComposeString): ComposeString = when { | |
| this is Combined && other is Combined -> Combined(this.parts + other.parts) | |
| this is Combined -> Combined(this.parts + other) | |
| other is Combined -> Combined(listOf(this) + other.parts) | |
| else -> Combined(listOf(this, other)) | |
| } | |
| /** | |
| * Represents a plain text string that does not require localization or resource lookup. | |
| * | |
| * @property text The raw string value to be displayed. | |
| */ | |
| data class Text(val text: String) : ComposeString { | |
| override suspend fun asString(): String = text | |
| @Composable | |
| override fun asStringComposable(): String = text | |
| } | |
| /** | |
| * Represents a standard string resource with optional formatting arguments. | |
| * | |
| * @property res The [StringResource] to be resolved. | |
| * @property args A list of arguments used for string formatting. | |
| */ | |
| data class Strings( | |
| val res: StringResource, | |
| val args: List<Any> = emptyList(), | |
| ) : ComposeString { | |
| // Helper constructor for varargs | |
| constructor(res: StringResource, vararg args: Any) : this(res, args.toList()) | |
| override suspend fun asString(): String { | |
| return getString(res, *args.toTypedArray()) | |
| } | |
| @Composable | |
| override fun asStringComposable(): String { | |
| return stringResource(res, *args.toTypedArray()) | |
| } | |
| } | |
| /** | |
| * Represents a pluralized string resource. | |
| * | |
| * @property res The plural string resource to be used. | |
| * @property quantity The quantity to use for selecting the appropriate plural form. | |
| * @property args Optional formatting arguments to be applied to the string. | |
| */ | |
| data class Plurals( | |
| val res: PluralStringResource, | |
| val quantity: Int, | |
| val args: List<Any> = emptyList(), | |
| ) : ComposeString { | |
| // Helper constructor for varargs | |
| constructor(res: PluralStringResource, quantity: Int, vararg args: Any) : this(res, quantity, args.toList()) | |
| override suspend fun asString(): String { | |
| return getPluralString(res, quantity, *args.toTypedArray()) | |
| } | |
| @Composable | |
| override fun asStringComposable(): String { | |
| return pluralStringResource(res, quantity, *args.toTypedArray()) | |
| } | |
| } | |
| /** | |
| * Represents a combination of multiple ComposeString instances. | |
| * | |
| * This implementation is automatically created when using the [plus] operator | |
| * to combine different ComposeString types. It concatenates all parts in order | |
| * when resolved. | |
| * | |
| * @property parts The list of ComposeString instances to combine. | |
| */ | |
| data class Combined( | |
| val parts: List<ComposeString>, | |
| ) : ComposeString { | |
| override suspend fun asString(): String { | |
| return buildString { | |
| parts.forEach { append(it.asString()) } | |
| } | |
| } | |
| @Composable | |
| override fun asStringComposable(): String { | |
| return buildString { | |
| parts.forEach { append(it.asStringComposable()) } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment