-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why is Res class internal? #4327
Comments
Thanks for an Issue! |
Hi! It is by design. To access resources from another module you need to export accessors from the library where resources are introduced. |
Interesting @pjBooms but what is the correct way to do that? |
@pjBooms you mean something like this? @OptIn(ExperimentalResourceApi::class)
object PublicRes {
object drawable {
val my_awesome_icon = Res.drawable.my_awesome_icon
}
} But what are the benefits of using Compose Resources library if I have to manually describe each resource? My usecase - reusable library of compose elements (single design system for all applications). |
Maybe an option to control the visibility of the generated Extracting all resources in one common lib for others is a good practice, IMO. |
As a temporary solution, you can add in the build.gradle.kts of "resource" module, the following code: // After executing the "generateComposeResClass" task, we replace the internal stuff by public.
tasks.named("generateComposeResClass") {
doLast {
val dirName = buildString {
val group = project.group.toString()
.lowercase()
.replace('.', '/')
.replace('-', '_')
append(group)
if (group.isNotEmpty()) {
append("/")
}
append(project.name.lowercase())
}
val dir = project.layout.buildDirectory
.dir("generated/compose/resourceGenerator/kotlin/$dirName/generated/resources")
.get()
.asFile
File(dir, "Res.kt").also {
if (!it.exists()) {
return@also
}
val content = it.readText()
val updatedContent = content.replace("internal object Res {", "object Res {")
it.writeText(updatedContent)
}
listOf("Drawable0.kt", "String0.kt").forEach { filename ->
File(dir, filename).also { file ->
if (!file.exists()) {
return@also
}
val content = file.readText()
val updatedContent = content.replace("internal val Res", "val Res")
file.writeText(updatedContent)
}
}
}
} After that, you can access to "Res" class of "resource" module in the others compose modules. |
no. it doesn't work because multimodule projects are not supported. The recommended way to do that is class ModuleRes {
fun getIconPainter() = painterResource(Res.module.icon)
} but againt it won't work until we support multimodule projects |
I see a lot of confusion about the internal-ness of the Res class. But I'll try to explain an initial idea behind that:
@Composable
fun getMyLibraryIconPainter(): Painter = painterResource(ID) It guaranties a stability of the API. Yes, it is not convenient for design-system or icon-pack libraries. I would generate the proposed code by the kotlin poet in my project for that :) Since there is a huge request to add the feature to the gradle plugin. I added the feature to my backlog and will investigate pros and cons and there is a chance to have it in the future releases. |
The main issue is almost all companies use something like Lokalise, and that means having only one module for resources and the rest of the modules depend on it. The use case of generating a public API would be interesting for a lot of people. |
To clarify why it is not a trivial task to change the class modifier only: because resources are packed different way on each target. So, to support the correct work with multimodule projects we have to be sure that the runtime may select correct path to read. |
@terrakok I'm sorry, but with all my great respect for you, I can't agree with that. Another example is compose web, which generates js and wasm files in one module of my application (composeApp). And I configured gradle so that the files generated by the compose plugin are copied to the build-folder of another module (server). And the ktor server serves these generated files as static resources. Something similar would be cool to implement with compose resources - during the build of the library with resources, the resource files are baked into the final artifact (jar) and accessible from the application using the library. And if I change something in the icon library, I'll just publish a new version of this library. And an application that uses the previous version will only see the previous version of the icons. And if you update the version, new versions of the icons will become available. |
Yikes, I didn't realise that Lokalise had this limitation of only one module having resources. That sort of thing definitely goes into the list of things to consider when choosing a translation vendor. |
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks. |
Hi guys, im trying to use the new feature of resources but i want to access to the resources of some common lib on another
but... the generated class is declerated as internal and i cant have access to that resources
can you check this use case?
The text was updated successfully, but these errors were encountered: