https://kotlinlang.org logo
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
benchmarks
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
confetti
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hiring-french
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
lincheck
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by
Title
f

Filip Wiesner

04/10/2023, 2:33 PM
I am trying to do
Input
component with
Modifiers
and I am struggling a little. Is there easier way to do this?
@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

David Herman

04/10/2023, 5:39 PM
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

Filip Wiesner

04/10/2023, 7:48 PM
ooooh! I din't realize I can just call
toAttrs
and pass a extension lambda. That makes sense
d

David Herman

04/10/2023, 8:55 PM
Ah! Sorry I missed that! Yes, it can occasionally be very convenient.
f

Filip Wiesner

04/11/2023, 8:59 AM
Would you consider adding "typed"
attrsModifier
, (instead of
AttrsScope<*>
) for similar usecases? Does that even make sense?
d

David Herman

04/11/2023, 7:46 PM
My apologies, I'm not following. Can you give a concrete example?
f

Filip Wiesner

04/11/2023, 7:55 PM
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
Modifier.attrsModifier<InputAttrsScope<String>> { onInput { ... } }
d

David Herman

04/11/2023, 7:56 PM
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

Filip Wiesner

04/11/2023, 7:58 PM
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

David Herman

04/11/2023, 7:59 PM
No worries, it's definitely an awkward part of kobweb
I totally understand why C4W uses typed scopes instead of modifiers
f

Filip Wiesner

04/11/2023, 8:01 PM
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

David Herman

04/11/2023, 8:03 PM
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

Filip Wiesner

04/11/2023, 8:08 PM
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

David Herman

04/11/2023, 8:08 PM
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

Filip Wiesner

04/11/2023, 8:10 PM
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

David Herman

04/11/2023, 8:23 PM
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

Filip Wiesner

04/11/2023, 8:27 PM
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

David Herman

04/11/2023, 8:34 PM
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

Filip Wiesner

04/11/2023, 8:38 PM
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

David Herman

04/11/2023, 8:38 PM
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

Filip Wiesner

04/11/2023, 8:42 PM
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

David Herman

04/11/2023, 8:43 PM
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

Filip Wiesner

04/11/2023, 8:44 PM
I mean API design
d

David Herman

04/11/2023, 8:44 PM
Maybe I need to create a Kobweb IntelliJ plugin to help with refactoring 😄
f

Filip Wiesner

04/11/2023, 8:45 PM
Maybe in future that would be nice :D
d

David Herman

04/11/2023, 8:45 PM
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

Filip Wiesner

04/11/2023, 8:46 PM
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

David Herman

04/11/2023, 8:47 PM
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

Filip Wiesner

04/11/2023, 8:48 PM
My problem with it is that it's not transparent. But again, maybe that's just my inexperience with web development
d

David Herman

04/11/2023, 8:49 PM
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

Filip Wiesner

04/11/2023, 8:51 PM
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