Skip to content

Commit

Permalink
support for css classes
Browse files Browse the repository at this point in the history
  • Loading branch information
reubenfirmin committed Oct 18, 2024
1 parent b490397 commit 54af3a4
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Speaking of which, you can of course use js libraries. Check out how `Sortable`

## CSS

Demo #6 above demonstrates the inline css dsl. Everything else uses tailwind classes.
Demo #6 above demonstrates the css dsl, which . Everything else uses tailwind classes.

## Components

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ kotlin {
implementation("org.jetbrains.kotlin-wrappers:kotlin-js")
implementation("org.jetbrains.kotlin-wrappers:kotlin-browser")
implementation("org.jetbrains.kotlin-wrappers:kotlin-css")

// implementation("org.jetbrains.kotlin-wrappers:kotlin-emotion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3")
implementation("org.jetbrains.kotlinx:kotlinx-html-js:0.11.0")
implementation(npm("tailwindcss", "3.4.4"))
Expand Down
5 changes: 5 additions & 0 deletions src/jsMain/kotlin/org/example/framework/interop/Connect.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.example.framework.interop
import kotlinx.html.TagConsumer
import web.dom.Element
import kotlinx.html.dom.append
import web.html.HTMLCollection
import web.html.HTMLElement

fun Element.clear() {
Expand All @@ -13,3 +14,7 @@ fun Element.clear() {

// bridge between kotlinx.html (which is still on org.w3c.dom) and the kotlin-browser wrapper, which uses the web.dom api
fun HTMLElement.appendTo(): TagConsumer<*> = this.unsafeCast<org.w3c.dom.HTMLElement>().append

fun <T : Element> HTMLCollection<T>.firstOrNull(): T? {
return if (length > 0) get(0) else null
}
32 changes: 32 additions & 0 deletions src/jsMain/kotlin/org/example/framework/interop/Css.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package org.example.framework.interop

import kotlinx.css.CssBuilder
import kotlinx.html.CommonAttributeGroupFacade
import kotlinx.html.classes
import kotlinx.html.style
import web.dom.document
import web.html.HTMLStyleElement

/**
* Worried about performance of inlining css? Don't be. https://danielnagy.me/posts/Post_tsr8q6sx37pl
Expand All @@ -13,3 +16,32 @@ fun CommonAttributeGroupFacade.css(block: CssBuilder.() -> Unit) {
block()
}.toString().removeSuffix("\n")
}

var counter = 0

/**
* Creates a class and attaches it to the head. Sets the current element's classname either to something specific if supplied,
* or a generated value.
* According to the video above, this is not as performant as inlining styles, or tailwind.
*/
fun CommonAttributeGroupFacade.cssClass(className: String = "clzz${counter++}", block: CssBuilder.() -> Unit) {
val rawCss = CssBuilder().apply(block).toString()
val formattedCss = rawCss.split(";")
.map { it.trim() }
.filter { it.isNotEmpty() }
.joinToString(";\n ")
val style = """
.$className {
$formattedCss;
}
""".trimIndent()

val head = document.head
val styleTag = head.getElementsByTagName("style").firstOrNull() as? HTMLStyleElement
?: document.createElement("style").also { head.appendChild(it) } as HTMLStyleElement

styleTag.innerHTML += "\n$style"

this.classes = setOf(className) + this.classes
}

19 changes: 19 additions & 0 deletions src/jsMain/kotlin/org/example/pages/home/StyleCard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import kotlinx.html.FlowContent
import kotlinx.html.div
import kotlinx.html.p
import org.example.framework.interop.css
import org.example.framework.interop.cssClass

fun FlowContent.styleCard() {
div("w-full") {
Expand All @@ -29,6 +30,7 @@ fun FlowContent.styleCard() {
timing = Timing.linear,
iterationCount = IterationCount.infinite
)
position = Position.relative
}
div {
css {
Expand Down Expand Up @@ -59,5 +61,22 @@ fun FlowContent.styleCard() {
}
}
}

// this is an example of css class support
div {
cssClass {
position = Position.absolute
bottom = 16.px
right = 16.px
width = 12.px
height = 12.px
backgroundColor = Color.cyan
borderRadius = 50.pct
border = Border(width = 1.px, color = Color.cyan, style = BorderStyle.solid)
overflow = Overflow.hidden
display = Display.inlineBlock
fontSize = 0.px
}
}
}
}

0 comments on commit 54af3a4

Please sign in to comment.