All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.styled.StyleSheet.kt Maven / Gradle / Ivy

There is a newer version: 5.3.11-pre.717
Show newest version
package styled

import kotlinx.css.CssBuilder
import kotlinx.css.RuleSet
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty0

open class StyleSheet(var name: String, val isStatic: Boolean = false) {
    private var isLoaded = false

    private val holders: MutableList = mutableListOf()

    constructor(name: String, parent: StyleSheet, isStatic: Boolean = false) : this(parent.name + "-" + name, isStatic)

    fun dependsOn(handler: () -> StyleSheet) {
        handler().inject()
    }

    fun css(vararg parents: RuleSet, builder: RuleSet) =
        CssHolder(this, *parents, builder)
            .also { addCssHolder(it) }

    internal fun addCssHolder(holder: CssHolder) {
        holders.add(holder)
    }

    fun inject() {
        if (!isLoaded && isStatic) {
            isLoaded = true

            val keys = holders
                .flatMap { cssHolder ->
                    cssHolder.properties.map { it to cssHolder }
                }

            val builder = CssBuilder(allowClasses = false).apply {
                keys.forEach {
                    ".${getClassName(it.first)}" {
                        for (r in it.second.ruleSets) {
                            r()
                        }
                    }
                }
            }

            injectGlobal(builder.toString())
            holders.clear()
        }
    }
}

class CssHolder(private val sheet: StyleSheet, internal vararg val ruleSets: RuleSet) {
    private val _properties: MutableList> = mutableListOf()

    val properties: List>
        get() = _properties

    operator fun provideDelegate(thisRef: Any?, providingProperty: KProperty<*>): ReadOnlyProperty {
        _properties.add(providingProperty)
        return ReadOnlyProperty { _, property ->
            {
                if (sheet.isStatic) {
                    +(sheet.getClassName(property))
                    sheet.inject()
                }

                if (!sheet.isStatic || !allowClasses) {
                    styleName.add(sheet.getClassName(property))
                    ruleSets.forEach { it() }
                }
            }
        }
    }
}

fun  T.getClassName(getClass: (T) -> KProperty0): String {
    return getClassName(getClass(this))
}

private fun StyleSheet.getClassName(property: KProperty<*>): String {
    return "$name-${property.name}"
}

fun  T.getClassSelector(getClass: (T) -> KProperty0): String {
    return ".${getClassName(getClass)}"
}

/**
 * Use this function to assign a CSS class without any properties to an element
 */
fun StyleSheet.cssMarker() =
    CssHolder(this, {})
        .also { addCssHolder(it) }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy