I am trying to do `Input` component with `Modifier...
# kobweb
f
I am trying to do
Input
component with
Modifiers
and I am struggling a little. Is there easier way to do this?
Copy code
@Composable
fun MyTextField(
    value: String,
    onValueChange: (String) -> Unit,
    type: InputType<String> = InputType.Text,
) {
    Input(
        type = type,
        attrs = Modifier
            .attrsModifier(inputAttrs(value, onValueChange) as AttrsScope<*>.() -> Unit)
            .toAttrs()
    )
}

private fun inputAttrs(
    value: String,
    onValueChange: (String) -> Unit
): InputAttrsScope<String>.() -> Unit = {
    value(value)
    onInput { onValueChange(it.value) }
}
d
I eventually want to create a Silk input widget! But you can take a look at
kobweb create examples/chat
for some examples of how I'm wrapping inputs in my own code.
f
ooooh! I din't realize I can just call
toAttrs
and pass a extension lambda. That makes sense
d
Ah! Sorry I missed that! Yes, it can occasionally be very convenient.
f
Would you consider adding "typed"
attrsModifier
, (instead of
AttrsScope<*>
) for similar usecases? Does that even make sense?
d
My apologies, I'm not following. Can you give a concrete example?
f
Maybe it does not make sense but the use case is my original question.
attrsModifier
lamda has
AttrsScope<*>.() -> Unit
signature so I cannot access functions of specific attr scope (like
InputAttrsScope
in the example). The only way to add is with
toAttrs {}
which is "typed" to attr scope of the element it is applied to
So basically I want to do
Copy code
Modifier.attrsModifier<InputAttrsScope<String>> { onInput { ... } }
d
Ah the problem there is chaining I think
If you type any single one it breaks the ability to chain I think? I might be wrong. I'll take a look
Of course, if you force a type and it's wrong, you'll get a runtime exception
Honestly, it's probably the same as just casting yourself?
f
Yeah, maybe it's bad idea to enable this in general 😅 It was just the first thing that came into my head when trying to implement custom
Input
d
No worries, it's definitely an awkward part of kobweb
I totally understand why C4W uses typed scopes instead of modifiers
f
Yeah but the modifier system is android friendly so I appreciate it. Even though you advise against in-line modifiers in favour of styles.
So basically the modifiers are in a weird place where they shoudn't be used but are actually available everywhere 🤔
d
Honestly, I'm still exploring what best practices are! In kobweb, inline styles may actually be easier to use in many cases, and unlike css, you have kotlin's type system to help you
Well, it's not that modifiers should not be used, but that you should try putting your modifiers in component styles instead of inline
Component Styles allow a few extra features that inline styles don't, like modifying visited link colors. Also, it can be nice to separate out your UX styling from your UI layout, to keep the layout code a little leaner... But if you're using inline styles and it's working for you I think that's great!
Elements that take attributes are kind of a tough spot. I think the way moving forward is for Silk to provide its own widgets so you never use Input directly again 😎
f
The main disadvantage for me is that I can't pass parameters to them and must create variants. I am just so used to the Android world where everything can be tweaked with change of one parameter. Bu I guess this is the "web" way of doing this.
d
Silk widgets will try to look more like Android widgets (I think)
Take a bunch of parameters that get translated to attributes behind the scenes
f
But I feel like that goes agains the idea of styles 😕 I am trying to make clear boundaries for me of what to put into style and what to put into parameter but I am still lost rn
Don't get me wrong, I like being lost a little. The process of discovering the right path is the best thing in programming but I see two clear paths and it's hard to find something in middle
Does that make sense? 😄 I want to use both approaches but they cannot be combined because I can't pass parameters into styles 🤷
d
Styles, even in Compose, are global
Modifiers apply to all widgets
For everything else, there are method parameters
Those loosely correspond to attributes in web
That's my thinking anyway
f
But in web context the styles are not just colors and shapes. It's also border, font, animations etc.. So the parallel does not really work for me. Also modifiers in "Skia Compose" are more of a decorator rather than attributes so order matters.
Anyways, right now I am going with the
ComponentStyle
approach and I'll see when (if) it will be limiting me
d
Yeah, that's true
But yeah the mental model I have is that modifiers in Kobweb are things that can apply to everything and anything else will be a method parameter
f
Yes, that works but that does not answer my "ComponentStyle vs Inline" approach. I still don't see the line of when to use what but that might be just my inexperience with web technologies
d
Oh yeah, that's fair. I don't think there's a right answer there
I originally wasn't going to even support component styles until I realized there were some subtle differences
What I'm mostly doing now is inline styles for one off elements, and I create a component style whenever I create a widget
Silk widgets will always use styles so that users can override them if they need to at startup, and also the variants concept is useful too
f
I don't think there's a right answer there
Exactly and there are a few problems I face • migrating from one approach to another is not straight forward because of need of migrating function parameters into component variants • you cannot easily combine both of them. I mean technically you can but from UI component design perspective it's not easy task • you have to use styles for pseudo elements/selectors
d
Yes, pseudo selectors too, that's right
I'll say they're easy to combine technically, using modifier.then(...), but sounds like you're talking about design
f
I mean API design
d
Maybe I need to create a Kobweb IntelliJ plugin to help with refactoring 😄
f
Maybe in future that would be nice :D
d
API design, all silk widgets take a Modifier and a variant, then internally call: Style.toModifier(variant).then(modifier)
If Kobweb gets to the point that a custom IntelliJ plugin would be worth working on I'd be so happy
f
API design, all silk widgets take a Modifier and a variant
Yeah I do the same with my components. Let's see how it works out
But I must say I am skeptical 😄
d
I think that's perfect! You shouldn't get in trouble with that approach
Good, it's good to have people around me being skeptical, I appreciate it!
f
My problem with it is that it's not transparent. But again, maybe that's just my inexperience with web development
d
I suspect webdevs have to learn this distinction too
I'm happy to hear how you feel about it over time
I am hoping to move docs to my site soon, hopefully I can document things clearer there once I can break things up into separate pages
f
I'm happy to hear how you feel about it over time
Don't you worry about that. I like talking about code and code design 😄 So I think this is not our last 50+ message thread