You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.3 KiB
128 lines
4.3 KiB
/* |
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
*/ |
|
|
|
@file:Suppress("NOTHING_TO_INLINE", "unused") |
|
|
|
package org.jetbrains.compose.web.css |
|
|
|
import kotlin.properties.ReadOnlyProperty |
|
|
|
|
|
interface StyleBuilder { |
|
fun property(propertyName: String, value: StylePropertyValue) |
|
fun variable(variableName: String, value: StylePropertyValue) |
|
|
|
operator fun <TValue: StylePropertyValue> CSSVariable<TValue>.invoke(value: TValue) { |
|
variable(name, value.toString()) |
|
} |
|
|
|
operator fun CSSVariable<StylePropertyString>.invoke(value: String) { |
|
variable(name, value) |
|
} |
|
|
|
operator fun CSSVariable<StylePropertyNumber>.invoke(value: Number) { |
|
variable(name, value) |
|
} |
|
} |
|
|
|
fun StyleBuilder.property(propertyName: String, value: String) |
|
= property(propertyName, value.unsafeCast<StylePropertyValue>()) |
|
fun StyleBuilder.property(propertyName: String, value: Number) |
|
= property(propertyName, value.unsafeCast<StylePropertyValue>()) |
|
fun StyleBuilder.variable(variableName: String, value: String) |
|
= variable(variableName, value.unsafeCast<StylePropertyValue>()) |
|
fun StyleBuilder.variable(variableName: String, value: Number) |
|
= variable(variableName, value.unsafeCast<StylePropertyValue>()) |
|
|
|
external interface CSSVariableValueAs<out T: StylePropertyValue> |
|
|
|
// after adding `variable` word `add` became ambiguous |
|
@Deprecated( |
|
"use property instead, will remove it soon", |
|
ReplaceWith("property(propertyName, value)") |
|
) |
|
fun StyleBuilder.add( |
|
propertyName: String, |
|
value: StylePropertyValue |
|
) = property(propertyName, value) |
|
|
|
interface CSSVariables |
|
|
|
class CSSVariable<out TValue: StylePropertyValue>(val name: String) |
|
|
|
private inline fun <TValue : StylePropertyValue?> variableValue(variableName: String, fallback: TValue? = null) = |
|
"var(--$variableName${fallback?.let { ", $it" } ?: ""})".unsafeCast<TValue>() |
|
|
|
fun <TValue: StylePropertyValue> CSSVariable<TValue>.value(fallback: TValue? = null): TValue = |
|
variableValue( |
|
name, |
|
fallback |
|
) |
|
|
|
fun <TValue> CSSVariable<TValue>.value(fallback: TValue? = null): TValue |
|
where TValue: CSSVariableValueAs<TValue>, TValue: StylePropertyValue |
|
= |
|
variableValue( |
|
name, |
|
fallback |
|
) |
|
|
|
fun <TValue: StylePropertyValue> CSSVariables.variable() = |
|
ReadOnlyProperty<Any?, CSSVariable<TValue>> { _, property -> |
|
CSSVariable(property.name) |
|
} |
|
|
|
interface StyleHolder { |
|
val properties: StylePropertyList |
|
val variables: StylePropertyList |
|
} |
|
|
|
@Suppress("EqualsOrHashCode") |
|
open class StyleBuilderImpl : StyleBuilder, StyleHolder { |
|
override val properties: MutableStylePropertyList = mutableListOf() |
|
override val variables: MutableStylePropertyList = mutableListOf() |
|
|
|
override fun property(propertyName: String, value: StylePropertyValue) { |
|
properties.add(StylePropertyDeclaration(propertyName, value)) |
|
} |
|
|
|
override fun variable(variableName: String, value: StylePropertyValue) { |
|
variables.add(StylePropertyDeclaration(variableName, value)) |
|
} |
|
|
|
// StylePropertyValue is js native object without equals |
|
override fun equals(other: Any?): Boolean { |
|
return if (other is StyleHolder) { |
|
properties.nativeEquals(other.properties) && |
|
variables.nativeEquals(other.variables) |
|
} else false |
|
} |
|
|
|
internal fun copyFrom(sb: StyleBuilderImpl) { |
|
properties.addAll(sb.properties) |
|
variables.addAll(sb.variables) |
|
} |
|
} |
|
|
|
data class StylePropertyDeclaration( |
|
val name: String, |
|
val value: StylePropertyValue |
|
) { |
|
constructor(name: String, value: String) : this(name, value.unsafeCast<StylePropertyValue>()) |
|
constructor(name: String, value: Number) : this(name, value.unsafeCast<StylePropertyValue>()) |
|
} |
|
typealias StylePropertyList = List<StylePropertyDeclaration> |
|
typealias MutableStylePropertyList = MutableList<StylePropertyDeclaration> |
|
|
|
fun StylePropertyList.nativeEquals(properties: StylePropertyList): Boolean { |
|
if (this.size != properties.size) return false |
|
|
|
var index = 0 |
|
return all { prop -> |
|
val otherProp = properties[index++] |
|
prop.name == otherProp.name && |
|
prop.value.toString() == otherProp.value.toString() |
|
} |
|
}
|
|
|