David Herman
05/20/2024, 4:21 PMComponentStyle
concept to the CssStyle
concept. In many cases, it's the same feature with a different name; but in other ways, it is a refactoring which has allowed us to correct longstanding issues with the original feature.
I wrote a lot more about this in the release notes, so please do check them out. This is a release that everyone with an active Kobweb codebase should upgrade to sooner than later, but do not upgrade to it blindly.
We're genuinely hoping the migration is smooth for almost everybody, but if you do upgrade and have issues, feel free to respond in this post's thread.David Herman
05/20/2024, 4:25 PMRafael Tonholo
05/20/2024, 7:55 PM@InitSilk
within a layer("reset")
, however, there are other issues that will take a while to figure out why they are happening.
Is there any guidance explaining how the new CssStyle is layered, so I could have a better picture of where to look?David Herman
05/20/2024, 8:28 PMreset
, component-styles
, component-variants
, restricted-styles
, and general-styles
(least precedence to most). I assume you are familiar with layers based on how you wrote your last message, but for any style you define that is not in an explicit layer, they will take precedence over all of those.
If you are seeing weird style selector priority issues, that means you are defining styles in your own code that you expected to have less precedence to Silk styles?
As you might expect, declaring styles using the CssStyle
method results in the following layers:
CssStyle { ... }
-> general-styles
CssStyle<ComponentKind> { ... }
-> component-styles
SomeStyle.addVariant { ... }
-> comonent-variants
class SomeClass : CssStyle.Restricted(...)
-> restricted-styles
while in @InitSilk
doing something like ctx.stylesheet.registerStyle("a") { ... }
is unlayered by default.Rafael Tonholo
05/20/2024, 8:44 PMregisterStyleBase
, as you stated, is not being layered, and for that reason, it is taking precedence over all the other styles. To fix that I just put them under the reset layer. I'm just not sure if that should be the expected behaviour. When I create a base style, I expect all my other styles to override it as I create new styles, but the way it is now is the opposite.
2. The rest of the issues were related to Silk components. I was doing some overrides on foundation components (Row, Column) to lay them out differently when mobile/desktop or even hiding it. As these components' classes are not layered, they were taking precedence over the custom style I've created. The fix was basically moving out from them to Div
instead.
Also, thank you for explaining how the layers are being chosen, that will facilitate me in the future.
And I need to say, the kobwebMigrateToCssStyle
task did a very good job during the migration 🙂David Herman
05/20/2024, 8:51 PMWhen I create a base style, I expect all my other styles to override it as I create new styles, but the way it is now is the opposite.Thanks for the feedback. I will think about that today. Using the
reset
layer will indeed work and should be safe to do so, although I can appreciate maybe you want another category name you can use (something I wedge between "reset" and "component-styles"). (The reset name comes from the idea of a CSS reset, as in how people reset inconsistent styles introduced by different browsers and also to make up mistakes due to legacy decisions; and that's not really what your styles are, here)
I was doing some overrides on foundation componentsJust curious, how were you overriding them?
And I need to say, theGlad to hear a positive data point, thanks! It's one thing to write and test it on our end, another thing entirely to run it out in the wild across everyone's projects...task did a very good job during the migration 🙂kobwebMigrateToCssStyle
David Herman
05/20/2024, 9:39 PMregisterStyle
and registerStyleBase
methods, which by default now applies them to a base
layer which sits between reset
and component-styles
. (In other words, you should be able to remove your reset layer hack and not specify any layer actually and things should work as before). If you try it and it works for you, let me know!Rafael Tonholo
05/20/2024, 11:47 PMJust curious, how were you overriding them?Just adding a style. Here is an example of what I was doing:
val AppBarActionButtonsStyle = CssStyle {
base {
Modifier.display(DisplayStyle.None)
}
Breakpoint.MD {
Modifier
.display(DisplayStyle.Flex)
.gap(10.dp)
}
}
@Composable
fun AppBar() {
// another stuff
Row(
modifier = AppBarActionButtonsStyle.toModifier(),
) {
ColorModeButton(
modifier = Modifier.alignSelf(AlignSelf.FlexEnd),
)
LanguageChanger(
selected = selectedLanguage,
onLocaleChange = onLocaleChange,
)
}
}
In the above example, I hide the row when it is on mobile because these action items show inside a dialog in that case.
In another case, I was creating an adaptive layout where on Desktop it shows as a row and on mobile shows as a column:
val AdaptiveLayoutStyles = CssStyle {
base {
Modifier
.display(DisplayStyle.Flex)
.flexDirection(FlexDirection.Column)
}
Breakpoint.LG {
Modifier
.flexDirection(FlexDirection.Row)
}
}
@Composable
actual fun AdaptiveLayout(
modifier: Modifier,
listPanel: @Composable () -> Unit,
detailPanel: @Composable () -> Unit,
) {
val adaptiveLayoutModifier = AdaptiveLayoutStyles.toModifier()
val responsiveAlignment by responsiveStateOf(ResponsiveValues(base = Alignment.Center, lg = Alignment.TopStart))
Box(
modifier = adaptiveLayoutModifier then modifier,
contentAlignment = responsiveAlignment,
) {
listPanel()
detailPanel()
}
}
As Box uses the display: grid
, the flex-direction
never works and gets overridden because Box is not under a layer.
Probably I should not have used Box
in this case, but I came up with the idea of the Box
from Compose and that is why I chose it 😛Rafael Tonholo
05/20/2024, 11:49 PMThe reset name comes from the idea of a CSS resetThat is exactly what I was expecting for that layer, which is why I used the same layer when I fixed it in my end using 0.18.0. BTW, with 0.18.1-SNAPSHOT, the base styles work as I was expecting!! Thanks for adding the
base
layer, that makes it even better. Now I can separate what is a reset and what is just the base styleDavid Herman
05/20/2024, 11:50 PMDavid Herman
05/20/2024, 11:55 PM.kobweb-box
etc.) should be part of the base layer (or some new layer either with slightly more or less precedence than base
). But switching over to a Div seems like a reasonable choice to avoid worrying about it for now!David Herman
05/21/2024, 12:02 AMRow(Modifier.thenUnless(useRows) { Modifier.display(None) })
Column(Modifier.thenIf(useRows) { Modifier.display(None) }}
BTW I don't think it's relevant here actually, but FYI there's a special Alignment / Arrangement value called FromStyle
you can use: https://github.com/varabyte/kobweb/blob/ca7e45d7b102120ee6998c6d31fdf68e47af0ee4/f[…]e/src/jsMain/kotlin/com/varabyte/kobweb/compose/ui/Alignment.kt
It doesn't prevent Box, Row, and Col from being grids, but it will prevent them from setting alignment / justification values, in case that ever matters to you, since you're more comfortable getting in there and setting styles yourself.