CLOVIS
03/01/2023, 5:19 PM@Composable
fun Button(
…
onClick: suspend () -> Unit,
scope: CoroutineScope = rememberCoroutineScope(),
…
)
This pattern is very convenient because it allows to use coroutines in all events, and it allows the button to automatically display a loading indicator if the event is taking too long. However, there is no good place to document it… I cannot copy-paste the documentation on each component that uses this pattern.
I'm considering creating a concepts
or patterns
package in core
that would only contain 'fake symbols' that can be documented. They would never be used in an actual application, but it would be easy to refer to them in documentation. For example, a dummy type alias:
/**
* Explain the pattern here.
*/
typealias PatternName = Nothing // useless, takes no space in the final application
Do you think this approach is a good idea?
1️⃣ yes, using a typealias = Nothing
(but typealiases do not get their own pages in Dokka, so it would be hard to link to them)
2️⃣ yes, using an empty object
(but it will exist in the final binary)
3️⃣ no, use some kind of external documentation website (cannot see the explanation in the IntelliJ documentation popup, hard for users to know if the website matches the version of the library that they're using)
🔢 neutralLandry Norris
03/01/2023, 5:27 PMscope to run onClick. By default, it is cancelled when the view leaves the screen
CLOVIS
03/01/2023, 5:29 PMLandry Norris
03/01/2023, 5:31 PMCLOVIS
03/01/2023, 5:34 PMmolikuner
03/01/2023, 5:59 PM/**
* Your documentation here
*/
data class EventHandler(val handler: suspend () -> Unit, val scope: CoroutineScope)
/**
* Your other documentation here
*/
@Compose
fun eventHandler(scope: CoroutineScope = remeberCoroutineScope(), handler: suspend () -> Unit) = EventHandler(handler, scope)
While this introduces an extra allocation, Compose might be able to optimize it, if you annotate the class with @Stable
or so. Once muti-value inline classes land you might even be able to inline it again 🤔😄
(I've typed this in Slack, so no idea whether this actually works)Landry Norris
03/01/2023, 6:00 PMCLOVIS
03/01/2023, 7:15 PM() -> Unit
. That's fine for a button, but maybe some other component may have a different signature, or even return a value.
It's also very inconvenient to call, you've gone from
Button(onClick = {...}) {...}
to
Button(onClick = EventHandler(rememberCoroutineScope()) {...}) {...}
which is less than ideal.
In any case, my only issue with the current signature is that it's hard to document, which IMO is not worth actually changing it (the most important part is that it's easy to use and easy to read).val customScope = // custom scope
Foo(
first = {
// uses the default scope
},
second = {
customScope.async {
// forces the custom scope
}.await()
}
)
molikuner
03/01/2023, 7:25 PMButton(onClick = eventHandler { ... }) { ... }
And the issue about different types could be fixed using generics and overloading, but it's more boilerplate for the library for sure 🤔CLOVIS
03/01/2023, 7:26 PMeventHandler
becomes an inline Composable factory, but that's even harder to read for a new user or maintainmolikuner
03/01/2023, 7:28 PMeventHandler
above 🤔CLOVIS
03/01/2023, 7:30 PMmsink
03/01/2023, 7:55 PMCLOVIS
03/01/2023, 8:03 PMDavid Herman
03/05/2023, 4:14 PMCLOVIS
03/05/2023, 6:50 PM