Hi everyone, I'm trying to switch from Styled Comp...
# react
s
Hi everyone, I'm trying to switch from Styled Components to Emotion but I'm wondering how to change the
StyleSheet
from Styled CSS to Emotion CSS. Example:
Copy code
object Main : StyleSheet("MainStyle") {
    val headingBoldGrey by css {
            color = Colors.darkGrey
            +Font.quicksandBold
            fontSize = titleFontSizeMobile
        }
    }
}
What would be the best way to convert something like this?
t
emotion.css.css
function will return you
ClassName
if you need it directly cc @Sergei Grishchenko
s
Cheers @turansky Do you by chance have any examples on this? I know you're quite an expert in this space.
t
Expected:
Copy code
import emotion.css.css

object Main {
    val headingBoldGrey:ClassName = css {
            color = Colors.darkGrey
            fontSize = titleFontSizeMobile
        }
    }
}
Or probably
emotion.styled.styled
will be fine solution for you 🙂
❤️ 1
s
Odd... Still getting an error with this. It seems it's not reading the types from the css class
t
Please try this function locally
Copy code
inline fun ClassName(
    crossinline block: PropertiesBuilder.() -> Unit,
): ClassName =
    emotion.css.css(jso(block))
Now we use similar internally
Planned package -
emotion.css
s
Awesome. Cheers @turansky Just a final one on this. How do you extend styles?
Copy code
val heading  = ClassName {
    display = Display.flex
    flexDirection = FlexDirection.row
    whiteSpace = WhiteSpace.pre
    alignItems = AlignItems.center
    +Font.quickSandRegular
    fontSize = font_medium
    +desktopHeadingFontSize
}

val titleGrey  = ClassName {
    +heading
    color = Colors.darkGrey
}
In
styled
it was done with a plus but I'm getting errors on the
+
?
t
I use
cx
for class names merge
s
What is that?
t
It’s emotion utility function
It’s
css
extension with “base” class names
s
Copy code
val heading  = ClassName {
    display = Display.flex
    flexDirection = FlexDirection.row
    whiteSpace = WhiteSpace.pre
    alignItems = AlignItems.center
    +Font.quickSandRegular
    fontSize = font_medium
    cx(desktopHeadingFontSize)
}
Awesome! Thank you 😄
t
One more
ClassName
:
Copy code
inline fun ClassName(
    vararg classNames: ClassName?,
    crossinline block: PropertiesBuilder.() -> Unit,
): ClassName =
    // impl (css + cx)
Both functions are internal now
s
Could this be converted into a
+
operator on the
cx
function so it would autocorrect globally? example:
Copy code
val titleGrey  = ClassName {
    +heading
    color = Colors.darkGrey
}
t
On current moment we want to avoid such
+
usages
Now we have “zero runtime” in case of css wrappers.
+heading
will require additional runtime, which we don’t want
s
Gotcha! Perfect. Thank you so much for the advice. 😄 K
t
If
ClassName
factories are fine for you - probably we will mark them as
public
s
Oh you legend 🐕
Last q! How do we deal with
media
tags in emotion kotlin?
t
Released in
pre.342
😎 1
How do we deal with
media
tags in emotion kotlin?
Do you mean media queries?
👍 1
a
@Sean Keane, here is the sample of media query usage. Hope this helps https://github.com/karakum-team/kotlin-mui-showcase/blob/main/src/main/kotlin/team/karakum/App.kt#L27
s
This is perfect @aerialist Thank you so much for the example! 😃
d
How can i do this without MUI (react, emotion)?
s
Emotion is separate css-in-js library, it is no linked with MUI, so am I understood correctly, that you want to stile something but without any frameworks?
d
Oh, I'm afraid I didn't make myself clear. In the example, the function from MUI is used. However, I do not use MUI and would like to do media queries as described on the emotion website (https://emotion.sh/docs/media-queries), but I am not sure what the syntax is for this. The simple form seems to work as string. But how can i create arry from the example?
Copy code
private val footer_inner = ClassName {
    display = Display.flex
    flexDirection = FlexDirection.columnReverse
    ....

    "@media (min-width: 48em)" {
        flexDirection = FlexDirection.row
        justifyContent = JustifyContent.spaceBetween
        paddingBottom = 4.2.rem
        paddingTop = 4.2.rem
    }
}
s
There is some misunderstanding from my side too, what example do you mean? If you are saying about example from @aerialist , so it is not CSS media query. There is browser API that allows to trigger some actions by media request. Hook
useMediaQuery
from MUI wraps this API and returns boolean flag that indicates if query is applicable or not. But I guess, it is not what you are looking for 🙂 Let's do next thing, you will write CSS code you want to implement and will try to help writing the same one but in Kotlin + Emotion
By the way your example with invitation on string in CSS builder looks like right direction
s
@Sergei Grishchenko I too am struggling a little to convert the styles. Do you have any idea on what might be the best approach here?
Copy code
val common = ClassName(Font.quicksandBold) {
    borderStyle = BorderStyle.none
    transition(duration = 0.3.s)
    focus {
        outline = Outline.none
    }
    hover {
        boxShadow += BoxShadow(
            false,
            dropShadow_xs,
            dropShadow_s,
            dropShadow_sm,
            -dropShadow_s,
            Colors.hoverShadowButton.darken(small_shadow_percentage)
        )

        transform {
            scale(small_scale)
        }
    }
    active {
        boxShadow += BoxShadow(
            false,
            dropShadow_xxs,
            dropShadow_xs,
            dropShadow_s,
            dropShadow_xxs,
            color = Colors.hoverShadowButton.darken(xsmall_percentage)
        )
        transform {
            scale(xsmall_scale)
        }
    }
}
f
Using this:
Copy code
val heading  = ClassName {
    display = Display.flex
    flexDirection = FlexDirection.row
    whiteSpace = WhiteSpace.pre
    alignItems = AlignItems.center
    +Font.quickSandRegular
    fontSize = font_medium
    +desktopHeadingFontSize
}
@turansky Is it possible to also get the name of the class in the html markup? Right now i am getting something like class=“uqqe9” but i want:
div class="heading"
Copy code
inline fun ClassName(
    crossinline block: PropertiesBuilder.() -> Unit,
): ClassName =
    emotion.css.css(jso(block))
@turansky are you re-pasting this in every component which needds it? Are there advantages using emotion vs. MUI or do you use both?
t
Are there advantages using emotion vs. MUI or do you use both?
I use
emotion
In case of MUI recommended ‘CSS in JS’ engine -
emotion
- we use it in our examples
Is it possible to also get the name of the class in the html markup?
We know only about this option - https://emotion.sh/docs/labels (check required) Will it work for you? Or you need exact name?
f
@turansky if label works it’s fine enough, i’ll give it a try. Thanks a lot
@Sean Keane Have you managed to use active? I mean
Copy code
ClassName(Font.quicksandBold) {
  active {
...
s
@Florent Martin I have had a nightmare 2 weeks. Somehow water got into my MacBook and I’ve had to send it away to get repaired. I just got it back yesterday and will be back on this in the next couple of days and I’ll let you know.
I really do appreciate the advice and help. Thank you both @turansky and @Florent MartinKotlin
f
@Sean Keane Good luck
I could solve my own question using css on an “active” react router NavLink
Copy code
css {
    width = 100.pct
    color = Color("#FFF")
    "&.active" {
         color = Color("green")
s
2500 problems resolved later and now it compiles... But it compiles without CSS? All I get are classes named "css-0" with no CSS inside?
Copy code
js {
    browser {
        commonWebpackConfig {
            cssSupport {
                enabled = true
            }
        }
        runTask {
            cssSupport {
                enabled = true
            }
        }
    }
    binaries.executable()
}
Am I missing something here? I also get an IR error when compiling with IR... So swapped to legacy for now.
Ok, Library sync issue was what the IR compiler was shouting about. No CSS generation was me being an idiot. 😂 Dont do this:
Copy code
css {
    cx(OverviewStyles.heading)
}
Do this:
Copy code
css(OverviewStyles.heading){}
311 Views