Igor Yakovlev
2 years ago
132 changed files with 4767 additions and 875 deletions
@ -0,0 +1,2 @@ |
|||||||
|
AGFzbQEAAAABBQFgAAF/AhIBA2VudgZtZW1vcnkCAYACgAIDAgEABwsBB19yZW5kZXIAAApJAUcBA38DQCAAQaAGbCECQQAhAQNAIAEgAmpBAnRBgAhqQf+BgHg2AgAgAUEBaiIBQaAGRw0ACyAAQQFqIgBBkANHDQALQYAICw== |
||||||
|
AGFzbQEAAAABBQFgAAF/AhIBA2VudgZtZW1vcnkCAYACgAIDAgEABwsBB19yZW5kZXIAAApJAUcBA38DQCAAQaAGbCECQQAhAQNAIAEgAmpBAnRBgAhqQf+BgHg2AgAgAUEBaiIBQaAGRw0ACyAAQQFqIgBBkANHDQALQYAICw== -d |
@ -1 +1 @@ |
|||||||
Subproject commit adf295be1d7ab30f6ab1d291c7f05475b6c50937 |
Subproject commit 8c92cdc4f55931657ce157212723e426a0248d24 |
Binary file not shown.
@ -0,0 +1,5 @@ |
|||||||
|
distributionBase=GRADLE_USER_HOME |
||||||
|
distributionPath=wrapper/dists |
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip |
||||||
|
zipStoreBase=GRADLE_USER_HOME |
||||||
|
zipStorePath=wrapper/dists |
@ -1,7 +1,6 @@ |
|||||||
#!/bin/bash |
#!/bin/bash |
||||||
|
|
||||||
cd "$(dirname "$0")" |
cd "$(dirname "$0")" |
||||||
|
|
||||||
pushd .. |
pushd .. |
||||||
./gradlew $COMPOSE_DEFAULT_GRADLE_ARGS "$@" || exit 1 |
./gradlew $COMPOSE_DEFAULT_GRADLE_ARGS "$@" || exit 1 |
||||||
popd |
popd |
@ -1,3 +1,4 @@ |
|||||||
kotlin.code.style=official |
kotlin.code.style=official |
||||||
kotlin.version=1.7.10 |
kotlin.version=1.8.255-SNAPSHOT |
||||||
compose.version=1.2.0 |
compose.version=1.2.0 |
||||||
|
compose.plugin.path=/Users/Igor.Yakovlev/.m2/repository/org/jetbrains/compose/compiler/compiler/0.1.0-SNAPSHOT/compiler-0.1.0-SNAPSHOT.jar |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,159 @@ |
|||||||
|
package core |
||||||
|
|
||||||
|
import androidx.compose.runtime.MutableState |
||||||
|
import androidx.compose.runtime.State |
||||||
|
import androidx.compose.runtime.mutableStateOf |
||||||
|
import data.GameFrame |
||||||
|
import data.Tube |
||||||
|
|
||||||
|
@JsFun("() => new Date().getTime()") |
||||||
|
external fun getTime(): Double |
||||||
|
|
||||||
|
/** |
||||||
|
* Game logic |
||||||
|
*/ |
||||||
|
class ComposeBirdGame : Game { |
||||||
|
|
||||||
|
companion object { |
||||||
|
const val COLUMNS = 15 |
||||||
|
const val ROWS = 9 |
||||||
|
const val BIRD_COLUMN = 1 |
||||||
|
private const val TUBES_START_FROM = (COLUMNS * 0.75).toInt() |
||||||
|
const val TOTAL_TUBES = 10 |
||||||
|
private const val TUBE_HORIZONTAL_DISTANCE = 3 |
||||||
|
private const val TUBE_VERTICAL_DISTANCE = 3 |
||||||
|
private const val TUBE_WEIGHT = 500 |
||||||
|
private const val BIRD_WEIGHT = 300 |
||||||
|
} |
||||||
|
|
||||||
|
private val tubeGapRange = TUBE_VERTICAL_DISTANCE until ROWS |
||||||
|
private var tubeLastSteppedAt = 0.0 |
||||||
|
private var birdLastSteppedAt = 0.0 |
||||||
|
private var shouldMoveBirdUp = false |
||||||
|
|
||||||
|
private val _gameFrame: MutableState<GameFrame> by lazy { |
||||||
|
mutableStateOf( |
||||||
|
// First frame |
||||||
|
GameFrame( |
||||||
|
birdPos = ROWS / 2, |
||||||
|
tubes = buildLevel(), |
||||||
|
isGameOver = false, |
||||||
|
isGameWon = false, |
||||||
|
score = 0 |
||||||
|
) |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* To build a random level |
||||||
|
*/ |
||||||
|
private fun buildLevel(): List<Tube> { |
||||||
|
return mutableListOf<Tube>().apply { |
||||||
|
var tubesAdded = 0 |
||||||
|
var tubePosition = 0 |
||||||
|
while (tubesAdded < TOTAL_TUBES) { |
||||||
|
if (tubePosition > TUBES_START_FROM && tubePosition % TUBE_HORIZONTAL_DISTANCE == 0) { // To give space to each tube |
||||||
|
add( |
||||||
|
Tube( |
||||||
|
tubePosition, |
||||||
|
buildRandomTube() |
||||||
|
) |
||||||
|
) |
||||||
|
tubesAdded++ |
||||||
|
} |
||||||
|
tubePosition++ |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* To build a random vertical tube/pipe |
||||||
|
*/ |
||||||
|
private fun buildRandomTube(): List<Boolean> { |
||||||
|
// creating a full tube |
||||||
|
val tube = mutableListOf<Boolean>().apply { |
||||||
|
repeat(ROWS) { |
||||||
|
add(true) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Adding gaps in random middle positions to make it two tubes. |
||||||
|
val gap1 = tubeGapRange.random() |
||||||
|
repeat(TUBE_VERTICAL_DISTANCE) { index -> |
||||||
|
tube[gap1 - index] = false |
||||||
|
} |
||||||
|
|
||||||
|
return tube |
||||||
|
} |
||||||
|
|
||||||
|
override val gameFrame: State<GameFrame> = _gameFrame |
||||||
|
|
||||||
|
override fun step() { |
||||||
|
update { |
||||||
|
val now = getTime() |
||||||
|
|
||||||
|
// Stepping tube |
||||||
|
val tubeDiff = now - tubeLastSteppedAt |
||||||
|
val newTubes = if (tubeDiff > TUBE_WEIGHT) { |
||||||
|
tubeLastSteppedAt = now |
||||||
|
tubes.map { |
||||||
|
it.copy(position = it.position - 1) |
||||||
|
} |
||||||
|
} else { |
||||||
|
tubes |
||||||
|
} |
||||||
|
|
||||||
|
// Stepping bird position |
||||||
|
val birdDiff = now - birdLastSteppedAt |
||||||
|
val newBirdPos = when { |
||||||
|
shouldMoveBirdUp -> { |
||||||
|
birdLastSteppedAt = now |
||||||
|
shouldMoveBirdUp = false |
||||||
|
birdPos - 1 // move up |
||||||
|
} |
||||||
|
birdDiff > BIRD_WEIGHT -> { |
||||||
|
birdLastSteppedAt = now |
||||||
|
birdPos + 1 // move down |
||||||
|
} |
||||||
|
else -> { |
||||||
|
birdPos |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val newScore = newTubes.filter { it.position < BIRD_COLUMN }.size // All passed tube |
||||||
|
val newIsGameWon = newScore >= TOTAL_TUBES // If all tubes passed |
||||||
|
|
||||||
|
// Checking if bird gone out |
||||||
|
val newIsGameOver = if (newBirdPos < 0 || newBirdPos >= ROWS || isCollidedWithTube(newBirdPos, tubes)) { |
||||||
|
true |
||||||
|
} else { |
||||||
|
isGameOver |
||||||
|
} |
||||||
|
|
||||||
|
copy( |
||||||
|
isGameOver = newIsGameOver, |
||||||
|
tubes = newTubes, |
||||||
|
birdPos = newBirdPos, |
||||||
|
score = newScore, |
||||||
|
isGameWon = newIsGameWon |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* To check if the bird collided with the tube (collision-detection) |
||||||
|
*/ |
||||||
|
private fun isCollidedWithTube(newBirdPos: Int, tubes: List<Tube>): Boolean { |
||||||
|
val birdTube = tubes.find { it.position == BIRD_COLUMN } |
||||||
|
return birdTube?.coordinates?.get(newBirdPos) ?: false |
||||||
|
} |
||||||
|
|
||||||
|
override fun moveBirdUp() { |
||||||
|
shouldMoveBirdUp = true |
||||||
|
} |
||||||
|
|
||||||
|
private inline fun update(func: GameFrame.() -> GameFrame) { |
||||||
|
_gameFrame.value = _gameFrame.value.func() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
package core |
||||||
|
|
||||||
|
import androidx.compose.runtime.State |
||||||
|
import data.GameFrame |
||||||
|
|
||||||
|
/** |
||||||
|
* A generic game interface |
||||||
|
*/ |
||||||
|
interface Game { |
||||||
|
val gameFrame: State<GameFrame> |
||||||
|
fun step() |
||||||
|
fun moveBirdUp() |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
package data |
||||||
|
|
||||||
|
data class GameFrame( |
||||||
|
val birdPos: Int, |
||||||
|
val tubes: List<Tube>, |
||||||
|
val isGameOver: Boolean, |
||||||
|
val isGameWon : Boolean, |
||||||
|
val score: Int, |
||||||
|
) |
@ -0,0 +1,6 @@ |
|||||||
|
package data |
||||||
|
|
||||||
|
data class Tube( |
||||||
|
var position: Int, |
||||||
|
val coordinates: List<Boolean> |
||||||
|
) |
@ -0,0 +1,136 @@ |
|||||||
|
import androidx.compose.runtime.Composable |
||||||
|
import androidx.compose.runtime.LaunchedEffect |
||||||
|
import androidx.compose.runtime.getValue |
||||||
|
import core.ComposeBirdGame |
||||||
|
import core.Game |
||||||
|
import data.GameFrame |
||||||
|
import kotlinx.browser.document |
||||||
|
import kotlinx.browser.window |
||||||
|
import kotlinx.coroutines.delay |
||||||
|
import org.jetbrains.compose.web.attributes.InputType |
||||||
|
import org.jetbrains.compose.web.attributes.disabled |
||||||
|
import org.jetbrains.compose.web.css.marginTop |
||||||
|
import org.jetbrains.compose.web.css.px |
||||||
|
import org.jetbrains.compose.web.dom.* |
||||||
|
import org.jetbrains.compose.web.renderComposable |
||||||
|
import org.w3c.dom.HTMLElement |
||||||
|
import org.w3c.dom.events.KeyboardEvent |
||||||
|
import org.w3c.dom.get |
||||||
|
|
||||||
|
fun main() { |
||||||
|
|
||||||
|
val game: Game = ComposeBirdGame() |
||||||
|
|
||||||
|
val body = document.getElementsByTagName("body")[0] as HTMLElement |
||||||
|
|
||||||
|
// Enabling keyboard control |
||||||
|
body.addEventListener("keyup", { |
||||||
|
when ((it as KeyboardEvent).keyCode) { |
||||||
|
38 -> { // Arrow up |
||||||
|
game.moveBirdUp() |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
renderComposable(rootElementId = "root") { |
||||||
|
|
||||||
|
Div( |
||||||
|
attrs = { |
||||||
|
style { |
||||||
|
property("text-align", "center") |
||||||
|
} |
||||||
|
} |
||||||
|
) { |
||||||
|
|
||||||
|
// The current frame! |
||||||
|
val gameFrame by game.gameFrame |
||||||
|
|
||||||
|
// Igniting the game loop |
||||||
|
LaunchedEffect(Unit) { |
||||||
|
while (!gameFrame.isGameOver) { |
||||||
|
delay(60) |
||||||
|
game.step() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Header(gameFrame) |
||||||
|
|
||||||
|
Div( |
||||||
|
attrs = { |
||||||
|
style { |
||||||
|
marginTop(30.px) |
||||||
|
} |
||||||
|
} |
||||||
|
) { |
||||||
|
if (gameFrame.isGameOver || gameFrame.isGameWon) { |
||||||
|
GameResult(gameFrame) |
||||||
|
} else { |
||||||
|
// Play area |
||||||
|
repeat(ComposeBirdGame.ROWS) { rowIndex -> |
||||||
|
Div { |
||||||
|
repeat(ComposeBirdGame.COLUMNS) { columnIndex -> |
||||||
|
Input( |
||||||
|
InputType.Radio, |
||||||
|
|
||||||
|
attrs = { |
||||||
|
val tube = gameFrame.tubes.find { it.position == columnIndex } |
||||||
|
val isTube = tube?.coordinates?.get(rowIndex) ?: false |
||||||
|
val isBird = |
||||||
|
!isTube && columnIndex == ComposeBirdGame.BIRD_COLUMN && rowIndex == gameFrame.birdPos |
||||||
|
|
||||||
|
// if it's either a tube node or bird, check it |
||||||
|
checked(isTube || isBird) |
||||||
|
|
||||||
|
if (!isBird) { |
||||||
|
// if it's a bird, enable it. (to change to blue color) |
||||||
|
disabled() |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Composable |
||||||
|
private fun Header(gameFrame: GameFrame) { |
||||||
|
// Game title |
||||||
|
H1 { |
||||||
|
Text(value = "🐦 Wasm Bird!") |
||||||
|
} |
||||||
|
|
||||||
|
// Game score |
||||||
|
Text(value = "Your Score: ${gameFrame.score} || Top Score: ${ComposeBirdGame.TOTAL_TUBES}") |
||||||
|
} |
||||||
|
|
||||||
|
@Composable |
||||||
|
private fun GameResult(gameFrame: GameFrame) { |
||||||
|
// Game Status |
||||||
|
H2 { |
||||||
|
if (gameFrame.isGameWon) { |
||||||
|
Text("🚀 Wasm the game! 🚀") |
||||||
|
} else { |
||||||
|
// core.Game over |
||||||
|
Text("💀 Wasm Over 💀") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Try Again |
||||||
|
Button( |
||||||
|
attrs = { |
||||||
|
onClick { |
||||||
|
window.location.reload() |
||||||
|
} |
||||||
|
} |
||||||
|
) { |
||||||
|
Text("Try Again!") |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<title>compose-bird</title> |
||||||
|
<style> |
||||||
|
input[type=radio]{ |
||||||
|
width:25px; |
||||||
|
height:25px; |
||||||
|
} |
||||||
|
</style> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div id="root"></div> |
||||||
|
<script type="module" src="web-compose-bird-wasm.mjs"></script> |
||||||
|
</body> |
||||||
|
</html> |
@ -1 +1 @@ |
|||||||
kotlin.version=1.7.10 |
kotlin.version=1.8.255-SNAPSHOT |
||||||
|
@ -1,71 +1,3 @@ |
|||||||
/* |
|
||||||
* 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. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.web.css |
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
operator fun <T: CSSUnit> CSSSizeValue<T>.times(num: Number): CSSSizeValue<T> = CSSUnitValueTyped(value * num.toFloat(), unit) |
actual external interface CSSCalcOperation<T : CSSUnit>: CSSNumericValue<T> |
||||||
operator fun <T: CSSUnit> Number.times(unit: CSSSizeValue<T>): CSSSizeValue<T> = CSSUnitValueTyped(unit.value * toFloat(), unit.unit) |
|
||||||
|
|
||||||
operator fun <T: CSSUnit> CSSSizeValue<T>.div(num: Number): CSSSizeValue<T> = CSSUnitValueTyped(value / num.toFloat(), unit) |
|
||||||
|
|
||||||
operator fun <T: CSSUnit> CSSSizeValue<T>.plus(b: CSSSizeValue<T>): CSSSizeValue<T> = CSSUnitValueTyped(value + b.value, unit) |
|
||||||
operator fun <T: CSSUnit> CSSSizeValue<T>.minus(b: CSSSizeValue<T>): CSSSizeValue<T> = CSSUnitValueTyped(value - b.value, unit) |
|
||||||
operator fun <T: CSSUnit> CSSSizeValue<T>.unaryMinus(): CSSSizeValue<T> = CSSUnitValueTyped(-value, unit) |
|
||||||
operator fun <T: CSSUnit> CSSSizeValue<T>.unaryPlus(): CSSSizeValue<T> = CSSUnitValueTyped(value, unit) |
|
||||||
|
|
||||||
external interface CSSCalcOperation<T : CSSUnit>: CSSNumericValue<T> |
|
||||||
|
|
||||||
data class CSSCalcValue<T : CSSUnit>( |
|
||||||
var op: CSSCalcOperation<out T> |
|
||||||
) : CSSCalcOperation<T> { |
|
||||||
override fun toString(): String = "calc$op" |
|
||||||
} |
|
||||||
|
|
||||||
private data class CSSPlus<T : CSSUnit>( |
|
||||||
var l: CSSNumericValue<out T>, |
|
||||||
var r: CSSNumericValue<out T> |
|
||||||
) : CSSCalcOperation<T> { |
|
||||||
override fun toString(): String = "($l + $r)" |
|
||||||
} |
|
||||||
|
|
||||||
private data class CSSMinus<T : CSSUnit>( |
|
||||||
var l: CSSNumericValue<out T>, |
|
||||||
var r: CSSNumericValue<out T> |
|
||||||
) : CSSCalcOperation<T> { |
|
||||||
override fun toString(): String = "($l - $r)" |
|
||||||
} |
|
||||||
|
|
||||||
private data class CSSTimes<T : CSSUnit>( |
|
||||||
var l: CSSNumericValue<out T>, |
|
||||||
var r: Number, |
|
||||||
val left: Boolean = true |
|
||||||
) : CSSCalcOperation<T> { |
|
||||||
override fun toString(): String = if (left) "($l * $r)" else "($r * $l)" |
|
||||||
} |
|
||||||
|
|
||||||
private data class CSSDiv<T : CSSUnit>( |
|
||||||
var l: CSSNumericValue<out T>, |
|
||||||
var r: Number |
|
||||||
) : CSSCalcOperation<T> { |
|
||||||
override fun toString(): String = "($l / $r)" |
|
||||||
} |
|
||||||
|
|
||||||
operator fun <T: CSSUnit> CSSNumericValue<out T>.plus(b: CSSNumericValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSPlus(this, b)) |
|
||||||
operator fun <T: CSSUnit> CSSCalcValue<out T>.plus(b: CSSNumericValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSPlus(this.op, b)) |
|
||||||
operator fun <T: CSSUnit> CSSNumericValue<out T>.plus(b: CSSCalcValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSPlus(this, b.op)) |
|
||||||
|
|
||||||
operator fun <T: CSSUnit> CSSNumericValue<out T>.minus(b: CSSNumericValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSMinus(this, b)) |
|
||||||
operator fun <T: CSSUnit> CSSCalcValue<out T>.minus(b: CSSNumericValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSMinus(this.op, b)) |
|
||||||
operator fun <T: CSSUnit> CSSNumericValue<out T>.minus(b: CSSCalcValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSMinus(this, b.op)) |
|
||||||
|
|
||||||
operator fun <T: CSSUnit> CSSCalcValue<out T>.times(b: Number): CSSCalcValue<T> = CSSCalcValue(CSSTimes(this.op, b)) |
|
||||||
operator fun <T: CSSUnit> Number.times(b: CSSCalcValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSTimes(b.op, this, false)) |
|
||||||
|
|
||||||
operator fun <T: CSSUnit> CSSNumericValue<T>.div(b: Number): CSSCalcValue<T> = CSSCalcValue(CSSDiv(this, b)) |
|
||||||
operator fun <T: CSSUnit> CSSCalcValue<out T>.div(b: Number): CSSCalcValue<T> = CSSCalcValue(CSSDiv(this.op, b)) |
|
||||||
|
|
||||||
operator fun <T: CSSUnit> CSSNumericValue<T>.times(b: Number): CSSCalcValue<T> = CSSCalcValue(CSSTimes(this, b)) |
|
||||||
operator fun <T: CSSUnit> Number.times(b: CSSNumericValue<T>): CSSCalcValue<T> = CSSCalcValue(CSSTimes(b, this, false)) |
|
||||||
|
|
@ -1,198 +1,3 @@ |
|||||||
@file:Suppress("unused", "MemberVisibilityCanBePrivate") |
|
||||||
|
|
||||||
package org.jetbrains.compose.web.css |
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
external interface CSSColorValue : StylePropertyValue, CSSVariableValueAs<CSSColorValue> |
actual external interface CSSColorValue : StylePropertyValue, CSSVariableValueAs<CSSColorValue> |
||||||
|
|
||||||
object Color { |
|
||||||
|
|
||||||
@Deprecated("use org.jetbrains.compose.web.css.rgb", ReplaceWith("rgb(r, g, b)")) |
|
||||||
data class RGB(val r: Number, val g: Number, val b: Number) : CSSColorValue { |
|
||||||
override fun toString(): String = "rgb($r, $g, $b)" |
|
||||||
} |
|
||||||
|
|
||||||
@Deprecated("use org.jetbrains.compose.web.css.rgba", ReplaceWith("rgba(r, g, b, a)")) |
|
||||||
data class RGBA(val r: Number, val g: Number, val b: Number, val a: Number) : CSSColorValue { |
|
||||||
override fun toString(): String = "rgba($r, $g, $b, $a)" |
|
||||||
} |
|
||||||
|
|
||||||
@Deprecated("use org.jetbrains.compose.web.css.hsl", ReplaceWith("hsl(h, s, l)")) |
|
||||||
data class HSL(val h: CSSAngleValue, val s: Number, val l: Number) : CSSColorValue { |
|
||||||
constructor(h: Number, s: Number, l: Number) : this(h.deg, s, l) |
|
||||||
|
|
||||||
override fun toString(): String = "hsl($h, $s%, $l%)" |
|
||||||
} |
|
||||||
|
|
||||||
@Deprecated("use org.jetbrains.compose.web.css.hsla", ReplaceWith("hsla(h, s, l, a)")) |
|
||||||
data class HSLA(val h: CSSAngleValue, val s: Number, val l: Number, val a: Number) : CSSColorValue { |
|
||||||
constructor(h: Number, s: Number, l: Number, a: Number) : this(h.deg, s, l, a) |
|
||||||
|
|
||||||
override fun toString(): String = "hsla($h, $s%, $l%, $a)" |
|
||||||
} |
|
||||||
|
|
||||||
inline val aliceblue get() = Color("aliceblue") |
|
||||||
inline val antiquewhite get() = Color("antiquewhite") |
|
||||||
inline val aquamarine get() = Color("aquamarine") |
|
||||||
inline val azure get() = Color("azure") |
|
||||||
inline val beige get() = Color("beige") |
|
||||||
inline val bisque get() = Color("bisque") |
|
||||||
inline val black get() = Color("black") |
|
||||||
inline val blanchedalmond get() = Color("blanchedalmond") |
|
||||||
inline val blue get() = Color("blue") |
|
||||||
inline val blueviolet get() = Color("blueviolet") |
|
||||||
inline val brown get() = Color("brown") |
|
||||||
inline val burlywood get() = Color("burlywood") |
|
||||||
inline val cadetblue get() = Color("cadetblue") |
|
||||||
inline val chartreuse get() = Color("chartreuse") |
|
||||||
inline val chocolate get() = Color("chocolate") |
|
||||||
inline val cornflowerblue get() = Color("cornflowerblue") |
|
||||||
inline val cornsilk get() = Color("cornsilk") |
|
||||||
inline val crimson get() = Color("crimson") |
|
||||||
inline val cyan get() = Color("cyan") |
|
||||||
inline val darkblue get() = Color("darkblue") |
|
||||||
inline val darkcyan get() = Color("darkcyan") |
|
||||||
inline val darkgoldenrod get() = Color("darkgoldenrod") |
|
||||||
inline val darkgray get() = Color("darkgray") |
|
||||||
inline val darkgreen get() = Color("darkgreen") |
|
||||||
inline val darkkhaki get() = Color("darkkhaki") |
|
||||||
inline val darkmagenta get() = Color("darkmagenta") |
|
||||||
inline val darkolivegreen get() = Color("darkolivegreen") |
|
||||||
inline val darkorange get() = Color("darkorange") |
|
||||||
inline val darkorchid get() = Color("darkorchid") |
|
||||||
inline val darkred get() = Color("darkred") |
|
||||||
inline val darksalmon get() = Color("darksalmon") |
|
||||||
inline val darkslateblue get() = Color("darkslateblue") |
|
||||||
inline val darkslategray get() = Color("darkslategray") |
|
||||||
inline val darkturquoise get() = Color("darkturquoise") |
|
||||||
inline val darkviolet get() = Color("darkviolet") |
|
||||||
inline val deeppink get() = Color("deeppink") |
|
||||||
inline val deepskyblue get() = Color("deepskyblue") |
|
||||||
inline val dimgray get() = Color("dimgray") |
|
||||||
inline val dodgerblue get() = Color("dodgerblue") |
|
||||||
inline val firebrick get() = Color("firebrick") |
|
||||||
inline val floralwhite get() = Color("floralwhite") |
|
||||||
inline val forestgreen get() = Color("forestgreen") |
|
||||||
inline val fuchsia get() = Color("fuchsia") |
|
||||||
inline val gainsboro get() = Color("gainsboro") |
|
||||||
inline val ghostwhite get() = Color("ghostwhite") |
|
||||||
inline val goldenrod get() = Color("goldenrod") |
|
||||||
inline val gold get() = Color("gold") |
|
||||||
inline val gray get() = Color("gray") |
|
||||||
inline val green get() = Color("green") |
|
||||||
inline val greenyellow get() = Color("greenyellow") |
|
||||||
inline val honeydew get() = Color("honeydew") |
|
||||||
inline val hotpink get() = Color("hotpink") |
|
||||||
inline val indianred get() = Color("indianred") |
|
||||||
inline val indigo get() = Color("indigo") |
|
||||||
inline val ivory get() = Color("ivory") |
|
||||||
inline val khaki get() = Color("khaki") |
|
||||||
inline val lavenderblush get() = Color("lavenderblush") |
|
||||||
inline val lavender get() = Color("lavender") |
|
||||||
inline val lawngreen get() = Color("lawngreen") |
|
||||||
inline val lemonchiffon get() = Color("lemonchiffon") |
|
||||||
inline val lightblue get() = Color("lightblue") |
|
||||||
inline val lightcoral get() = Color("lightcoral") |
|
||||||
inline val lightcyan get() = Color("lightcyan") |
|
||||||
inline val lightgoldenrodyellow get() = Color("lightgoldenrodyellow") |
|
||||||
inline val lightgray get() = Color("lightgray") |
|
||||||
inline val lightgreen get() = Color("lightgreen") |
|
||||||
inline val lightpink get() = Color("lightpink") |
|
||||||
inline val lightsalmon get() = Color("lightsalmon") |
|
||||||
inline val lightseagreen get() = Color("lightseagreen") |
|
||||||
inline val lightskyblue get() = Color("lightskyblue") |
|
||||||
inline val lightslategray get() = Color("lightslategray") |
|
||||||
inline val lightsteelblue get() = Color("lightsteelblue") |
|
||||||
inline val lightyellow get() = Color("lightyellow") |
|
||||||
inline val limegreen get() = Color("limegreen") |
|
||||||
inline val lime get() = Color("lime") |
|
||||||
inline val linen get() = Color("linen") |
|
||||||
inline val magenta get() = Color("magenta") |
|
||||||
inline val maroon get() = Color("maroon") |
|
||||||
inline val mediumaquamarine get() = Color("mediumaquamarine") |
|
||||||
inline val mediumblue get() = Color("mediumblue") |
|
||||||
inline val mediumorchid get() = Color("mediumorchid") |
|
||||||
inline val mediumpurple get() = Color("mediumpurple") |
|
||||||
inline val mediumseagreen get() = Color("mediumseagreen") |
|
||||||
inline val mediumslateblue get() = Color("mediumslateblue") |
|
||||||
inline val mediumspringgreen get() = Color("mediumspringgreen") |
|
||||||
inline val mediumturquoise get() = Color("mediumturquoise") |
|
||||||
inline val mediumvioletred get() = Color("mediumvioletred") |
|
||||||
inline val midnightblue get() = Color("midnightblue") |
|
||||||
inline val mintcream get() = Color("mintcream") |
|
||||||
inline val mistyrose get() = Color("mistyrose") |
|
||||||
inline val moccasin get() = Color("moccasin") |
|
||||||
inline val navajowhite get() = Color("navajowhite") |
|
||||||
inline val navi get() = Color("navi") |
|
||||||
inline val oldlace get() = Color("oldlace") |
|
||||||
inline val olivedrab get() = Color("olivedrab") |
|
||||||
inline val olive get() = Color("olive") |
|
||||||
inline val orange get() = Color("orange") |
|
||||||
inline val orangered get() = Color("orangered") |
|
||||||
inline val orchid get() = Color("orchid") |
|
||||||
inline val palegoldenrod get() = Color("palegoldenrod") |
|
||||||
inline val palegreen get() = Color("palegreen") |
|
||||||
inline val paleturquoise get() = Color("paleturquoise") |
|
||||||
inline val palevioletred get() = Color("palevioletred") |
|
||||||
inline val papayawhip get() = Color("papayawhip") |
|
||||||
inline val peachpuff get() = Color("peachpuff") |
|
||||||
inline val peru get() = Color("peru") |
|
||||||
inline val pink get() = Color("pink") |
|
||||||
inline val plum get() = Color("plum") |
|
||||||
inline val powderblue get() = Color("powderblue") |
|
||||||
inline val purple get() = Color("purple") |
|
||||||
inline val rebeccapurple get() = Color("rebeccapurple") |
|
||||||
inline val red get() = Color("red") |
|
||||||
inline val rosybrown get() = Color("rosybrown") |
|
||||||
inline val royalblue get() = Color("royalblue") |
|
||||||
inline val saddlebrown get() = Color("saddlebrown") |
|
||||||
inline val salmon get() = Color("salmon") |
|
||||||
inline val sandybrown get() = Color("sandybrown") |
|
||||||
inline val seagreen get() = Color("seagreen") |
|
||||||
inline val seashell get() = Color("seashell") |
|
||||||
inline val sienna get() = Color("sienna") |
|
||||||
inline val silver get() = Color("silver") |
|
||||||
inline val skyblue get() = Color("skyblue") |
|
||||||
inline val slateblue get() = Color("slateblue") |
|
||||||
inline val slategray get() = Color("slategray") |
|
||||||
inline val snow get() = Color("snow") |
|
||||||
inline val springgreen get() = Color("springgreen") |
|
||||||
inline val steelblue get() = Color("steelblue") |
|
||||||
inline val teal get() = Color("teal") |
|
||||||
inline val thistle get() = Color("thistle") |
|
||||||
inline val tomato get() = Color("tomato") |
|
||||||
inline val turquoise get() = Color("turquoise") |
|
||||||
inline val violet get() = Color("violet") |
|
||||||
inline val wheat get() = Color("wheat") |
|
||||||
inline val white get() = Color("white") |
|
||||||
inline val whitesmoke get() = Color("whitesmoke") |
|
||||||
inline val yellowgreen get() = Color("yellowgreen") |
|
||||||
inline val yellow get() = Color("yellow") |
|
||||||
|
|
||||||
inline val transparent get() = Color("transparent") |
|
||||||
inline val currentColor get() = Color("currentColor") |
|
||||||
} |
|
||||||
|
|
||||||
fun Color(name: String): CSSColorValue = name.unsafeCast<CSSColorValue>() |
|
||||||
|
|
||||||
private class RGB(val r: Number, val g: Number, val b: Number): CSSColorValue { |
|
||||||
override fun toString(): String = "rgb($r, $g, $b)" |
|
||||||
} |
|
||||||
|
|
||||||
private class RGBA(val r: Number, val g: Number, val b: Number, val a: Number) : CSSColorValue { |
|
||||||
override fun toString(): String = "rgba($r, $g, $b, $a)" |
|
||||||
} |
|
||||||
|
|
||||||
private class HSL(val h: CSSAngleValue, val s: Number, val l: Number) : CSSColorValue { |
|
||||||
override fun toString(): String = "hsl($h, $s%, $l%)" |
|
||||||
} |
|
||||||
|
|
||||||
private class HSLA(val h: CSSAngleValue, val s: Number, val l: Number, val a: Number) : CSSColorValue { |
|
||||||
override fun toString(): String = "hsla($h, $s%, $l%, $a)" |
|
||||||
} |
|
||||||
|
|
||||||
fun rgb(r: Number, g: Number, b: Number): CSSColorValue = RGB(r, g, b) |
|
||||||
fun rgba(r: Number, g: Number, b: Number, a: Number): CSSColorValue = RGBA(r, g, b, a) |
|
||||||
fun hsl(h: CSSAngleValue, s: Number, l: Number): CSSColorValue = HSL(h, s, l) |
|
||||||
fun hsl(h: Number, s: Number, l: Number): CSSColorValue = HSL(h.deg, s, l) |
|
||||||
fun hsla(h: CSSAngleValue, s: Number, l: Number, a: Number): CSSColorValue = HSLA(h, s, l, a) |
|
||||||
fun hsla(h: Number, s: Number, l: Number, a: Number): CSSColorValue = HSLA(h.deg, s, l, a) |
|
@ -1,195 +1,3 @@ |
|||||||
/* |
|
||||||
* 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 |
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
import org.jetbrains.compose.web.attributes.HtmlAttrMarker |
actual external interface CSSVariableValueAs<out T : StylePropertyValue> |
||||||
import org.jetbrains.compose.web.internal.runtime.ComposeWebInternalApi |
|
||||||
import kotlin.properties.ReadOnlyProperty |
|
||||||
|
|
||||||
@Deprecated( |
|
||||||
message = "Renamed to StyleScope", |
|
||||||
replaceWith = ReplaceWith("StyleScope", "org.jetbrains.compose.web.css.StyleScope") |
|
||||||
) |
|
||||||
typealias StyleBuilder = StyleScope |
|
||||||
|
|
||||||
/** |
|
||||||
* StyleScope serves for two main purposes. Passed as a builder context (in [AttrsScope]), it |
|
||||||
* makes it possible to: |
|
||||||
* 1. Add inlined css properties to the element (@see [property]) |
|
||||||
* 2. Set values to CSS variables (@see [variable]) |
|
||||||
*/ |
|
||||||
@HtmlAttrMarker |
|
||||||
interface StyleScope { |
|
||||||
/** |
|
||||||
* Adds arbitrary CSS property to the inline style of the element |
|
||||||
* @param propertyName - the name of css property as [per spec](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference) |
|
||||||
* @param value - the value, it can be either String or specialized type like [CSSNumeric] or [CSSColorValue] |
|
||||||
* |
|
||||||
* Most frequent CSS property values can be set via specialized methods, like [width], [display] etc. |
|
||||||
* |
|
||||||
* Example: |
|
||||||
* ``` |
|
||||||
* Div({ |
|
||||||
* style { |
|
||||||
* property("some-exotic-css-property", "I am a string value") |
|
||||||
* property("some-exotic-css-property-width", 5.px) |
|
||||||
* } |
|
||||||
* }) |
|
||||||
* ``` |
|
||||||
*/ |
|
||||||
fun property(propertyName: String, value: StylePropertyValue) |
|
||||||
fun variable(variableName: String, value: StylePropertyValue) |
|
||||||
|
|
||||||
fun property(propertyName: String, value: String) = property(propertyName, StylePropertyValue(value)) |
|
||||||
fun property(propertyName: String, value: Number) = property(propertyName, StylePropertyValue(value)) |
|
||||||
fun variable(variableName: String, value: String) = variable(variableName, StylePropertyValue(value)) |
|
||||||
fun variable(variableName: String, value: Number) = variable(variableName, StylePropertyValue(value)) |
|
||||||
|
|
||||||
operator fun <TValue : StylePropertyValue> CSSStyleVariable<TValue>.invoke(value: TValue) { |
|
||||||
variable(name, value.toString()) |
|
||||||
} |
|
||||||
|
|
||||||
operator fun CSSStyleVariable<StylePropertyString>.invoke(value: String) { |
|
||||||
variable(name, value) |
|
||||||
} |
|
||||||
|
|
||||||
operator fun CSSStyleVariable<StylePropertyNumber>.invoke(value: Number) { |
|
||||||
variable(name, value) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
internal inline fun variableValue(variableName: String, fallback: StylePropertyValue? = null) = |
|
||||||
"var(--$variableName${fallback?.let { ", $it" } ?: ""})" |
|
||||||
|
|
||||||
external interface CSSVariableValueAs<out T : StylePropertyValue> |
|
||||||
|
|
||||||
inline fun <TValue> CSSVariableValue(value: StylePropertyValue) = |
|
||||||
value.unsafeCast<TValue>() |
|
||||||
|
|
||||||
inline fun <TValue> CSSVariableValue(value: String) = |
|
||||||
CSSVariableValue<TValue>(StylePropertyValue(value)) |
|
||||||
|
|
||||||
// after adding `variable` word `add` became ambiguous |
|
||||||
@Deprecated( |
|
||||||
"use property instead, will remove it soon", |
|
||||||
ReplaceWith("property(propertyName, value)") |
|
||||||
) |
|
||||||
fun StyleScope.add( |
|
||||||
propertyName: String, |
|
||||||
value: StylePropertyValue |
|
||||||
) = property(propertyName, value) |
|
||||||
|
|
||||||
interface CSSVariable { |
|
||||||
val name: String |
|
||||||
} |
|
||||||
|
|
||||||
class CSSStyleVariable<out TValue : StylePropertyValue>(override val name: String) : CSSVariable |
|
||||||
|
|
||||||
fun <TValue : StylePropertyValue> CSSStyleVariable<TValue>.value(fallback: TValue? = null) = |
|
||||||
CSSVariableValue<TValue>( |
|
||||||
variableValue( |
|
||||||
name, |
|
||||||
fallback |
|
||||||
) |
|
||||||
) |
|
||||||
|
|
||||||
fun <TValue> CSSStyleVariable<TValue>.value(fallback: TValue? = null) |
|
||||||
where TValue : CSSVariableValueAs<TValue>, |
|
||||||
TValue : StylePropertyValue = |
|
||||||
CSSVariableValue<TValue>( |
|
||||||
variableValue( |
|
||||||
name, |
|
||||||
fallback |
|
||||||
) |
|
||||||
) |
|
||||||
|
|
||||||
/** |
|
||||||
* Introduces CSS variable that can be later referred anywhere in [StyleSheet] |
|
||||||
* |
|
||||||
* Example: |
|
||||||
* ``` |
|
||||||
* object AppCSSVariables { |
|
||||||
* val width by variable<CSSUnitValue>() |
|
||||||
* val stringHeight by variable<StylePropertyString>() |
|
||||||
* val order by variable<StylePropertyNumber>() |
|
||||||
* } |
|
||||||
* |
|
||||||
* object AppStylesheet : StyleSheet() { |
|
||||||
* val classWithProperties by style { |
|
||||||
* AppCSSVariables.width(100.px) |
|
||||||
* property("width", AppCSSVariables.width.value()) |
|
||||||
* } |
|
||||||
*``` |
|
||||||
* |
|
||||||
*/ |
|
||||||
fun <TValue : StylePropertyValue> variable() = |
|
||||||
ReadOnlyProperty<Any?, CSSStyleVariable<TValue>> { _, property -> |
|
||||||
CSSStyleVariable(property.name) |
|
||||||
} |
|
||||||
|
|
||||||
interface StyleHolder { |
|
||||||
@ComposeWebInternalApi |
|
||||||
val properties: StylePropertyList |
|
||||||
@ComposeWebInternalApi |
|
||||||
val variables: StylePropertyList |
|
||||||
} |
|
||||||
|
|
||||||
@Deprecated( |
|
||||||
message = "Renamed to StyleScopeBuilder", |
|
||||||
replaceWith = ReplaceWith("StyleScopeBuilder", "org.jetbrains.compose.web.css.StyleScopeBuilder") |
|
||||||
) |
|
||||||
typealias StyleBuilderImpl = StyleScopeBuilder |
|
||||||
|
|
||||||
@Suppress("EqualsOrHashCode") |
|
||||||
open class StyleScopeBuilder : StyleScope, 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 |
|
||||||
} |
|
||||||
|
|
||||||
@ComposeWebInternalApi |
|
||||||
internal fun copyFrom(sb: StyleHolder) { |
|
||||||
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> |
|
||||||
|
|
||||||
internal 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() |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,54 @@ |
|||||||
|
package org.jetbrains.compose.web |
||||||
|
|
||||||
|
import org.w3c.dom.events.* |
||||||
|
import org.w3c.dom.css.CSSRule |
||||||
|
import androidx.compose.web.events.* |
||||||
|
import org.jetbrains.compose.web.css.CSSStyleValue |
||||||
|
import org.w3c.dom.HTMLElement |
||||||
|
import org.w3c.dom.svg.SVGElement |
||||||
|
import org.jetbrains.compose.web.css.StylePropertyValue |
||||||
|
import org.jetbrains.compose.web.dom.RadioGroupScope |
||||||
|
import org.jetbrains.compose.web.dom.ElementBuilder |
||||||
|
import org.w3c.dom.Element |
||||||
|
|
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> SyntheticEvent<*>.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> CSSRule.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> CSSStyleValue.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> Event.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> EventTarget.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> String.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> Number.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> HTMLElement.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> SVGElement.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> StylePropertyValue.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
@ExperimentalComposeWebApi |
||||||
|
internal actual fun <T> RadioGroupScope<*>.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> ElementBuilder<*>.unsafeCast(): T = asDynamic().unsafeCast<T>() |
||||||
|
|
||||||
|
@PublishedApi |
||||||
|
internal actual fun Any.unsafeCastBoolean(): Boolean = asDynamic().unsafeCast<Boolean>() |
||||||
|
@PublishedApi |
||||||
|
internal actual fun Any.unsafeCastString(): String = asDynamic().unsafeCast<String>() |
||||||
|
|
||||||
|
@PublishedApi |
||||||
|
internal actual fun Any.getStringProperty(name: String): String? = asDynamic()[name] as String? |
||||||
|
@PublishedApi |
||||||
|
internal actual fun Any.getBooleanProperty(name: String): Boolean? = asDynamic()[name] as Boolean? |
||||||
|
@PublishedApi |
||||||
|
internal actual fun Any.getIntProperty(name: String): Int? = asDynamic()[name] as Int? |
||||||
|
@PublishedApi |
||||||
|
internal actual fun <T> Any.getAnyProperty(name: String): T = asDynamic()[name].unsafeCast<T>() |
||||||
|
|
||||||
|
internal actual fun Element.getAttributeNamesWorkaround(): Array<String> = getAttributeNames() |
@ -0,0 +1,14 @@ |
|||||||
|
/* |
||||||
|
* 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") |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.* |
||||||
|
|
||||||
|
expect interface CSSKeywordValue : CSSStyleValue |
||||||
|
|
||||||
|
inline fun CSSKeywordValue(value: String): CSSKeywordValue = CSSStyleValue(value).unsafeCast<CSSKeywordValue>() |
@ -0,0 +1,71 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
|
operator fun <T: CSSUnit> CSSSizeValue<T>.times(num: Number): CSSSizeValue<T> = CSSUnitValueTyped(value * num.toFloat(), unit) |
||||||
|
operator fun <T: CSSUnit> Number.times(unit: CSSSizeValue<T>): CSSSizeValue<T> = CSSUnitValueTyped(unit.value * toFloat(), unit.unit) |
||||||
|
|
||||||
|
operator fun <T: CSSUnit> CSSSizeValue<T>.div(num: Number): CSSSizeValue<T> = CSSUnitValueTyped(value / num.toFloat(), unit) |
||||||
|
|
||||||
|
operator fun <T: CSSUnit> CSSSizeValue<T>.plus(b: CSSSizeValue<T>): CSSSizeValue<T> = CSSUnitValueTyped(value + b.value, unit) |
||||||
|
operator fun <T: CSSUnit> CSSSizeValue<T>.minus(b: CSSSizeValue<T>): CSSSizeValue<T> = CSSUnitValueTyped(value - b.value, unit) |
||||||
|
operator fun <T: CSSUnit> CSSSizeValue<T>.unaryMinus(): CSSSizeValue<T> = CSSUnitValueTyped(-value, unit) |
||||||
|
operator fun <T: CSSUnit> CSSSizeValue<T>.unaryPlus(): CSSSizeValue<T> = CSSUnitValueTyped(value, unit) |
||||||
|
|
||||||
|
expect interface CSSCalcOperation<T : CSSUnit>: CSSNumericValue<T> |
||||||
|
|
||||||
|
data class CSSCalcValue<T : CSSUnit>( |
||||||
|
var op: CSSCalcOperation<out T> |
||||||
|
) : CSSCalcOperation<T> { |
||||||
|
override fun toString(): String = "calc$op" |
||||||
|
} |
||||||
|
|
||||||
|
private data class CSSPlus<T : CSSUnit>( |
||||||
|
var l: CSSNumericValue<out T>, |
||||||
|
var r: CSSNumericValue<out T> |
||||||
|
) : CSSCalcOperation<T> { |
||||||
|
override fun toString(): String = "($l + $r)" |
||||||
|
} |
||||||
|
|
||||||
|
private data class CSSMinus<T : CSSUnit>( |
||||||
|
var l: CSSNumericValue<out T>, |
||||||
|
var r: CSSNumericValue<out T> |
||||||
|
) : CSSCalcOperation<T> { |
||||||
|
override fun toString(): String = "($l - $r)" |
||||||
|
} |
||||||
|
|
||||||
|
private data class CSSTimes<T : CSSUnit>( |
||||||
|
var l: CSSNumericValue<out T>, |
||||||
|
var r: Number, |
||||||
|
val left: Boolean = true |
||||||
|
) : CSSCalcOperation<T> { |
||||||
|
override fun toString(): String = if (left) "($l * $r)" else "($r * $l)" |
||||||
|
} |
||||||
|
|
||||||
|
private data class CSSDiv<T : CSSUnit>( |
||||||
|
var l: CSSNumericValue<out T>, |
||||||
|
var r: Number |
||||||
|
) : CSSCalcOperation<T> { |
||||||
|
override fun toString(): String = "($l / $r)" |
||||||
|
} |
||||||
|
|
||||||
|
operator fun <T: CSSUnit> CSSNumericValue<out T>.plus(b: CSSNumericValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSPlus(this, b)) |
||||||
|
operator fun <T: CSSUnit> CSSCalcValue<out T>.plus(b: CSSNumericValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSPlus(this.op, b)) |
||||||
|
operator fun <T: CSSUnit> CSSNumericValue<out T>.plus(b: CSSCalcValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSPlus(this, b.op)) |
||||||
|
|
||||||
|
operator fun <T: CSSUnit> CSSNumericValue<out T>.minus(b: CSSNumericValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSMinus(this, b)) |
||||||
|
operator fun <T: CSSUnit> CSSCalcValue<out T>.minus(b: CSSNumericValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSMinus(this.op, b)) |
||||||
|
operator fun <T: CSSUnit> CSSNumericValue<out T>.minus(b: CSSCalcValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSMinus(this, b.op)) |
||||||
|
|
||||||
|
operator fun <T: CSSUnit> CSSCalcValue<out T>.times(b: Number): CSSCalcValue<T> = CSSCalcValue(CSSTimes(this.op, b)) |
||||||
|
operator fun <T: CSSUnit> Number.times(b: CSSCalcValue<out T>): CSSCalcValue<T> = CSSCalcValue(CSSTimes(b.op, this, false)) |
||||||
|
|
||||||
|
operator fun <T: CSSUnit> CSSNumericValue<T>.div(b: Number): CSSCalcValue<T> = CSSCalcValue(CSSDiv(this, b)) |
||||||
|
operator fun <T: CSSUnit> CSSCalcValue<out T>.div(b: Number): CSSCalcValue<T> = CSSCalcValue(CSSDiv(this.op, b)) |
||||||
|
|
||||||
|
operator fun <T: CSSUnit> CSSNumericValue<T>.times(b: Number): CSSCalcValue<T> = CSSCalcValue(CSSTimes(this, b)) |
||||||
|
operator fun <T: CSSUnit> Number.times(b: CSSNumericValue<T>): CSSCalcValue<T> = CSSCalcValue(CSSTimes(b, this, false)) |
||||||
|
|
@ -0,0 +1,249 @@ |
|||||||
|
@file:Suppress("Unused", "NOTHING_TO_INLINE", "NESTED_CLASS_IN_EXTERNAL_INTERFACE", "INLINE_EXTERNAL_DECLARATION", "WRONG_BODY_OF_EXTERNAL_DECLARATION", "NESTED_EXTERNAL_DECLARATION", "ClassName") |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
|
expect interface CSSNumericValue<T : CSSUnit> : StylePropertyValue, CSSVariableValueAs<CSSNumericValue<T>> |
||||||
|
|
||||||
|
expect interface CSSSizeValue<T : CSSUnit> : CSSNumericValue<T> { |
||||||
|
val value: Float |
||||||
|
val unit: T |
||||||
|
} |
||||||
|
|
||||||
|
data class CSSUnitValueTyped<T : CSSUnit>( |
||||||
|
override val value: Float, |
||||||
|
override val unit: T |
||||||
|
) : CSSSizeValue<T> { |
||||||
|
override fun toString(): String = "$value$unit" |
||||||
|
} |
||||||
|
|
||||||
|
interface CSSUnitLengthOrPercentage: CSSUnit |
||||||
|
interface CSSUnitPercentage: CSSUnitLengthOrPercentage |
||||||
|
interface CSSUnitLength: CSSUnitLengthOrPercentage |
||||||
|
interface CSSUnitRel : CSSUnitLength |
||||||
|
interface CSSUnitAbs: CSSUnitLength |
||||||
|
interface CSSUnitAngle: CSSUnit |
||||||
|
interface CSSUnitTime: CSSUnit |
||||||
|
interface CSSUnitFrequency: CSSUnit |
||||||
|
interface CSSUnitResolution: CSSUnit |
||||||
|
interface CSSUnitFlex: CSSUnit |
||||||
|
|
||||||
|
typealias CSSAngleValue = CSSSizeValue<out CSSUnitAngle> |
||||||
|
typealias CSSLengthOrPercentageValue = CSSSizeValue<out CSSUnitLengthOrPercentage> |
||||||
|
typealias CSSLengthValue = CSSSizeValue<out CSSUnitLength> |
||||||
|
typealias CSSPercentageValue = CSSSizeValue<out CSSUnitPercentage> |
||||||
|
typealias CSSUnitValue = CSSSizeValue<out CSSUnit> |
||||||
|
typealias CSSNumeric = CSSNumericValue<out CSSUnit> |
||||||
|
typealias CSSpxValue = CSSSizeValue<CSSUnit.px> |
||||||
|
|
||||||
|
// fake interfaces to distinguish units |
||||||
|
interface CSSUnit { |
||||||
|
interface percent: CSSUnitPercentage |
||||||
|
|
||||||
|
interface em: CSSUnitRel |
||||||
|
|
||||||
|
interface ex: CSSUnitRel |
||||||
|
|
||||||
|
interface ch: CSSUnitRel |
||||||
|
|
||||||
|
interface ic: CSSUnitRel |
||||||
|
|
||||||
|
interface rem: CSSUnitRel |
||||||
|
|
||||||
|
interface lh: CSSUnitRel |
||||||
|
|
||||||
|
interface rlh: CSSUnitRel |
||||||
|
|
||||||
|
interface vw: CSSUnitRel |
||||||
|
|
||||||
|
interface vh: CSSUnitRel |
||||||
|
|
||||||
|
interface vi: CSSUnitRel |
||||||
|
|
||||||
|
interface vb: CSSUnitRel |
||||||
|
|
||||||
|
interface vmin: CSSUnitRel |
||||||
|
|
||||||
|
interface vmax: CSSUnitRel |
||||||
|
|
||||||
|
interface cm: CSSUnitRel |
||||||
|
|
||||||
|
interface mm: CSSUnitRel |
||||||
|
|
||||||
|
interface Q: CSSUnitRel |
||||||
|
|
||||||
|
interface pt: CSSUnitAbs |
||||||
|
|
||||||
|
interface pc: CSSUnitAbs |
||||||
|
|
||||||
|
interface px: CSSUnitAbs |
||||||
|
|
||||||
|
interface deg: CSSUnitAngle |
||||||
|
|
||||||
|
interface grad: CSSUnitAngle |
||||||
|
|
||||||
|
interface rad: CSSUnitAngle |
||||||
|
|
||||||
|
interface turn: CSSUnitAngle |
||||||
|
|
||||||
|
interface s: CSSUnitTime |
||||||
|
|
||||||
|
interface ms: CSSUnitTime |
||||||
|
|
||||||
|
interface Hz: CSSUnitFrequency |
||||||
|
|
||||||
|
interface kHz: CSSUnitFrequency |
||||||
|
|
||||||
|
interface dpi: CSSUnitResolution |
||||||
|
|
||||||
|
interface dpcm: CSSUnitResolution |
||||||
|
|
||||||
|
interface dppx: CSSUnitResolution |
||||||
|
|
||||||
|
interface fr: CSSUnitFlex |
||||||
|
|
||||||
|
interface number: CSSUnit |
||||||
|
|
||||||
|
companion object { |
||||||
|
inline val percent get() = "%".unsafeCast<percent>() |
||||||
|
|
||||||
|
inline val em get() = "em".unsafeCast<em>() |
||||||
|
|
||||||
|
inline val ex get() = "ex".unsafeCast<ex>() |
||||||
|
|
||||||
|
inline val ch get() = "ch".unsafeCast<ch>() |
||||||
|
|
||||||
|
inline val ic get() = "ic".unsafeCast<ic>() |
||||||
|
|
||||||
|
inline val rem get() = "rem".unsafeCast<rem>() |
||||||
|
|
||||||
|
inline val lh get() = "lh".unsafeCast<lh>() |
||||||
|
|
||||||
|
inline val rlh get() = "rlh".unsafeCast<rlh>() |
||||||
|
|
||||||
|
inline val vw get() = "vw".unsafeCast<vw>() |
||||||
|
|
||||||
|
inline val vh get() = "vh".unsafeCast<vh>() |
||||||
|
|
||||||
|
inline val vi get() = "vi".unsafeCast<vi>() |
||||||
|
|
||||||
|
inline val vb get() = "vb".unsafeCast<vb>() |
||||||
|
|
||||||
|
inline val vmin get() = "vmin".unsafeCast<vmin>() |
||||||
|
|
||||||
|
inline val vmax get() = "vmax".unsafeCast<vmax>() |
||||||
|
|
||||||
|
inline val cm get() = "cm".unsafeCast<cm>() |
||||||
|
|
||||||
|
inline val mm get() = "mm".unsafeCast<mm>() |
||||||
|
|
||||||
|
inline val Q get() = "Q".unsafeCast<Q>() |
||||||
|
|
||||||
|
inline val pt get() = "pt".unsafeCast<pt>() |
||||||
|
|
||||||
|
inline val pc get() = "pc".unsafeCast<pc>() |
||||||
|
|
||||||
|
inline val px get() = "px".unsafeCast<px>() |
||||||
|
|
||||||
|
inline val deg get() = "deg".unsafeCast<deg>() |
||||||
|
|
||||||
|
inline val grad get() = "grad".unsafeCast<grad>() |
||||||
|
|
||||||
|
inline val rad get() = "rad".unsafeCast<rad>() |
||||||
|
|
||||||
|
inline val turn get() = "turn".unsafeCast<turn>() |
||||||
|
|
||||||
|
inline val s get() = "s".unsafeCast<s>() |
||||||
|
|
||||||
|
inline val ms get() = "ms".unsafeCast<ms>() |
||||||
|
|
||||||
|
inline val Hz get() = "Hz".unsafeCast<Hz>() |
||||||
|
|
||||||
|
inline val kHz get() = "kHz".unsafeCast<kHz>() |
||||||
|
|
||||||
|
inline val dpi get() = "dpi".unsafeCast<dpi>() |
||||||
|
|
||||||
|
inline val dpcm get() = "dpcm".unsafeCast<dpcm>() |
||||||
|
|
||||||
|
inline val dppx get() = "dppx".unsafeCast<dppx>() |
||||||
|
|
||||||
|
inline val fr get() = "fr".unsafeCast<fr>() |
||||||
|
|
||||||
|
inline val number get() = "number".unsafeCast<number>() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
val Number.number |
||||||
|
get(): CSSSizeValue<CSSUnit.number> = CSSUnitValueTyped(this.toFloat(), CSSUnit.number) |
||||||
|
|
||||||
|
val Number.percent |
||||||
|
get() : CSSSizeValue<CSSUnit.percent> = CSSUnitValueTyped(this.toFloat(), CSSUnit.percent) |
||||||
|
|
||||||
|
val Number.em |
||||||
|
get() : CSSSizeValue<CSSUnit.em> = CSSUnitValueTyped(this.toFloat(), CSSUnit.em) |
||||||
|
|
||||||
|
val Number.ex |
||||||
|
get(): CSSSizeValue<CSSUnit.ex> = CSSUnitValueTyped(this.toFloat(), CSSUnit.ex) |
||||||
|
|
||||||
|
val Number.ch |
||||||
|
get(): CSSSizeValue<CSSUnit.ch> = CSSUnitValueTyped(this.toFloat(), CSSUnit.ch) |
||||||
|
|
||||||
|
val Number.cssRem |
||||||
|
get(): CSSSizeValue<CSSUnit.rem> = CSSUnitValueTyped(this.toFloat(), CSSUnit.rem) |
||||||
|
|
||||||
|
val Number.vw |
||||||
|
get(): CSSSizeValue<CSSUnit.vw> = CSSUnitValueTyped(this.toFloat(), CSSUnit.vw) |
||||||
|
|
||||||
|
val Number.vh |
||||||
|
get(): CSSSizeValue<CSSUnit.vh> = CSSUnitValueTyped(this.toFloat(), CSSUnit.vh) |
||||||
|
|
||||||
|
val Number.vmin |
||||||
|
get(): CSSSizeValue<CSSUnit.vmin> = CSSUnitValueTyped(this.toFloat(), CSSUnit.vmin) |
||||||
|
|
||||||
|
val Number.vmax |
||||||
|
get(): CSSSizeValue<CSSUnit.vmax> = CSSUnitValueTyped(this.toFloat(), CSSUnit.vmax) |
||||||
|
|
||||||
|
val Number.cm |
||||||
|
get(): CSSSizeValue<CSSUnit.cm> = CSSUnitValueTyped(this.toFloat(), CSSUnit.cm) |
||||||
|
|
||||||
|
val Number.mm |
||||||
|
get(): CSSSizeValue<CSSUnit.mm> = CSSUnitValueTyped(this.toFloat(), CSSUnit.mm) |
||||||
|
|
||||||
|
val Number.Q |
||||||
|
get() : CSSSizeValue<CSSUnit.Q> = CSSUnitValueTyped(this.toFloat(), CSSUnit.Q) |
||||||
|
|
||||||
|
val Number.pt |
||||||
|
get(): CSSSizeValue<CSSUnit.pt> = CSSUnitValueTyped(this.toFloat(), CSSUnit.pt) |
||||||
|
val Number.pc |
||||||
|
get(): CSSSizeValue<CSSUnit.pc> = CSSUnitValueTyped(this.toFloat(), CSSUnit.pc) |
||||||
|
val Number.px |
||||||
|
get(): CSSSizeValue<CSSUnit.px> = CSSUnitValueTyped(this.toFloat(), CSSUnit.px) |
||||||
|
|
||||||
|
val Number.deg |
||||||
|
get(): CSSSizeValue<CSSUnit.deg> = CSSUnitValueTyped(this.toFloat(), CSSUnit.deg) |
||||||
|
val Number.grad |
||||||
|
get(): CSSSizeValue<CSSUnit.grad> = CSSUnitValueTyped(this.toFloat(), CSSUnit.grad) |
||||||
|
val Number.rad |
||||||
|
get(): CSSSizeValue<CSSUnit.rad> = CSSUnitValueTyped(this.toFloat(), CSSUnit.rad) |
||||||
|
val Number.turn |
||||||
|
get(): CSSSizeValue<CSSUnit.turn> = CSSUnitValueTyped(this.toFloat(), CSSUnit.turn) |
||||||
|
|
||||||
|
val Number.s |
||||||
|
get(): CSSSizeValue<CSSUnit.s> = CSSUnitValueTyped(this.toFloat(), CSSUnit.s) |
||||||
|
val Number.ms |
||||||
|
get(): CSSSizeValue<CSSUnit.ms> = CSSUnitValueTyped(this.toFloat(), CSSUnit.ms) |
||||||
|
|
||||||
|
val Number.Hz |
||||||
|
get(): CSSSizeValue<CSSUnit.Hz> = CSSUnitValueTyped(this.toFloat(), CSSUnit.Hz) |
||||||
|
val Number.kHz |
||||||
|
get(): CSSSizeValue<CSSUnit.kHz> = CSSUnitValueTyped(this.toFloat(), CSSUnit.kHz) |
||||||
|
|
||||||
|
val Number.dpi |
||||||
|
get(): CSSSizeValue<CSSUnit.dpi> = CSSUnitValueTyped(this.toFloat(), CSSUnit.dpi) |
||||||
|
val Number.dpcm |
||||||
|
get(): CSSSizeValue<CSSUnit.dpcm> = CSSUnitValueTyped(this.toFloat(), CSSUnit.dpcm) |
||||||
|
val Number.dppx |
||||||
|
get(): CSSSizeValue<CSSUnit.dppx> = CSSUnitValueTyped(this.toFloat(), CSSUnit.dppx) |
||||||
|
|
||||||
|
val Number.fr |
||||||
|
get(): CSSSizeValue<CSSUnit.fr> = CSSUnitValueTyped(this.toFloat(), CSSUnit.fr) |
@ -0,0 +1,198 @@ |
|||||||
|
@file:Suppress("unused", "MemberVisibilityCanBePrivate") |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
|
expect interface CSSColorValue : StylePropertyValue, CSSVariableValueAs<CSSColorValue> |
||||||
|
|
||||||
|
object Color { |
||||||
|
|
||||||
|
@Deprecated("use org.jetbrains.compose.web.css.rgb", ReplaceWith("rgb(r, g, b)")) |
||||||
|
data class RGB(val r: Number, val g: Number, val b: Number) : CSSColorValue { |
||||||
|
override fun toString(): String = "rgb($r, $g, $b)" |
||||||
|
} |
||||||
|
|
||||||
|
@Deprecated("use org.jetbrains.compose.web.css.rgba", ReplaceWith("rgba(r, g, b, a)")) |
||||||
|
data class RGBA(val r: Number, val g: Number, val b: Number, val a: Number) : CSSColorValue { |
||||||
|
override fun toString(): String = "rgba($r, $g, $b, $a)" |
||||||
|
} |
||||||
|
|
||||||
|
@Deprecated("use org.jetbrains.compose.web.css.hsl", ReplaceWith("hsl(h, s, l)")) |
||||||
|
data class HSL(val h: CSSAngleValue, val s: Number, val l: Number) : CSSColorValue { |
||||||
|
constructor(h: Number, s: Number, l: Number) : this(h.deg, s, l) |
||||||
|
|
||||||
|
override fun toString(): String = "hsl($h, $s%, $l%)" |
||||||
|
} |
||||||
|
|
||||||
|
@Deprecated("use org.jetbrains.compose.web.css.hsla", ReplaceWith("hsla(h, s, l, a)")) |
||||||
|
data class HSLA(val h: CSSAngleValue, val s: Number, val l: Number, val a: Number) : CSSColorValue { |
||||||
|
constructor(h: Number, s: Number, l: Number, a: Number) : this(h.deg, s, l, a) |
||||||
|
|
||||||
|
override fun toString(): String = "hsla($h, $s%, $l%, $a)" |
||||||
|
} |
||||||
|
|
||||||
|
inline val aliceblue get() = Color("aliceblue") |
||||||
|
inline val antiquewhite get() = Color("antiquewhite") |
||||||
|
inline val aquamarine get() = Color("aquamarine") |
||||||
|
inline val azure get() = Color("azure") |
||||||
|
inline val beige get() = Color("beige") |
||||||
|
inline val bisque get() = Color("bisque") |
||||||
|
inline val black get() = Color("black") |
||||||
|
inline val blanchedalmond get() = Color("blanchedalmond") |
||||||
|
inline val blue get() = Color("blue") |
||||||
|
inline val blueviolet get() = Color("blueviolet") |
||||||
|
inline val brown get() = Color("brown") |
||||||
|
inline val burlywood get() = Color("burlywood") |
||||||
|
inline val cadetblue get() = Color("cadetblue") |
||||||
|
inline val chartreuse get() = Color("chartreuse") |
||||||
|
inline val chocolate get() = Color("chocolate") |
||||||
|
inline val cornflowerblue get() = Color("cornflowerblue") |
||||||
|
inline val cornsilk get() = Color("cornsilk") |
||||||
|
inline val crimson get() = Color("crimson") |
||||||
|
inline val cyan get() = Color("cyan") |
||||||
|
inline val darkblue get() = Color("darkblue") |
||||||
|
inline val darkcyan get() = Color("darkcyan") |
||||||
|
inline val darkgoldenrod get() = Color("darkgoldenrod") |
||||||
|
inline val darkgray get() = Color("darkgray") |
||||||
|
inline val darkgreen get() = Color("darkgreen") |
||||||
|
inline val darkkhaki get() = Color("darkkhaki") |
||||||
|
inline val darkmagenta get() = Color("darkmagenta") |
||||||
|
inline val darkolivegreen get() = Color("darkolivegreen") |
||||||
|
inline val darkorange get() = Color("darkorange") |
||||||
|
inline val darkorchid get() = Color("darkorchid") |
||||||
|
inline val darkred get() = Color("darkred") |
||||||
|
inline val darksalmon get() = Color("darksalmon") |
||||||
|
inline val darkslateblue get() = Color("darkslateblue") |
||||||
|
inline val darkslategray get() = Color("darkslategray") |
||||||
|
inline val darkturquoise get() = Color("darkturquoise") |
||||||
|
inline val darkviolet get() = Color("darkviolet") |
||||||
|
inline val deeppink get() = Color("deeppink") |
||||||
|
inline val deepskyblue get() = Color("deepskyblue") |
||||||
|
inline val dimgray get() = Color("dimgray") |
||||||
|
inline val dodgerblue get() = Color("dodgerblue") |
||||||
|
inline val firebrick get() = Color("firebrick") |
||||||
|
inline val floralwhite get() = Color("floralwhite") |
||||||
|
inline val forestgreen get() = Color("forestgreen") |
||||||
|
inline val fuchsia get() = Color("fuchsia") |
||||||
|
inline val gainsboro get() = Color("gainsboro") |
||||||
|
inline val ghostwhite get() = Color("ghostwhite") |
||||||
|
inline val goldenrod get() = Color("goldenrod") |
||||||
|
inline val gold get() = Color("gold") |
||||||
|
inline val gray get() = Color("gray") |
||||||
|
inline val green get() = Color("green") |
||||||
|
inline val greenyellow get() = Color("greenyellow") |
||||||
|
inline val honeydew get() = Color("honeydew") |
||||||
|
inline val hotpink get() = Color("hotpink") |
||||||
|
inline val indianred get() = Color("indianred") |
||||||
|
inline val indigo get() = Color("indigo") |
||||||
|
inline val ivory get() = Color("ivory") |
||||||
|
inline val khaki get() = Color("khaki") |
||||||
|
inline val lavenderblush get() = Color("lavenderblush") |
||||||
|
inline val lavender get() = Color("lavender") |
||||||
|
inline val lawngreen get() = Color("lawngreen") |
||||||
|
inline val lemonchiffon get() = Color("lemonchiffon") |
||||||
|
inline val lightblue get() = Color("lightblue") |
||||||
|
inline val lightcoral get() = Color("lightcoral") |
||||||
|
inline val lightcyan get() = Color("lightcyan") |
||||||
|
inline val lightgoldenrodyellow get() = Color("lightgoldenrodyellow") |
||||||
|
inline val lightgray get() = Color("lightgray") |
||||||
|
inline val lightgreen get() = Color("lightgreen") |
||||||
|
inline val lightpink get() = Color("lightpink") |
||||||
|
inline val lightsalmon get() = Color("lightsalmon") |
||||||
|
inline val lightseagreen get() = Color("lightseagreen") |
||||||
|
inline val lightskyblue get() = Color("lightskyblue") |
||||||
|
inline val lightslategray get() = Color("lightslategray") |
||||||
|
inline val lightsteelblue get() = Color("lightsteelblue") |
||||||
|
inline val lightyellow get() = Color("lightyellow") |
||||||
|
inline val limegreen get() = Color("limegreen") |
||||||
|
inline val lime get() = Color("lime") |
||||||
|
inline val linen get() = Color("linen") |
||||||
|
inline val magenta get() = Color("magenta") |
||||||
|
inline val maroon get() = Color("maroon") |
||||||
|
inline val mediumaquamarine get() = Color("mediumaquamarine") |
||||||
|
inline val mediumblue get() = Color("mediumblue") |
||||||
|
inline val mediumorchid get() = Color("mediumorchid") |
||||||
|
inline val mediumpurple get() = Color("mediumpurple") |
||||||
|
inline val mediumseagreen get() = Color("mediumseagreen") |
||||||
|
inline val mediumslateblue get() = Color("mediumslateblue") |
||||||
|
inline val mediumspringgreen get() = Color("mediumspringgreen") |
||||||
|
inline val mediumturquoise get() = Color("mediumturquoise") |
||||||
|
inline val mediumvioletred get() = Color("mediumvioletred") |
||||||
|
inline val midnightblue get() = Color("midnightblue") |
||||||
|
inline val mintcream get() = Color("mintcream") |
||||||
|
inline val mistyrose get() = Color("mistyrose") |
||||||
|
inline val moccasin get() = Color("moccasin") |
||||||
|
inline val navajowhite get() = Color("navajowhite") |
||||||
|
inline val navi get() = Color("navi") |
||||||
|
inline val oldlace get() = Color("oldlace") |
||||||
|
inline val olivedrab get() = Color("olivedrab") |
||||||
|
inline val olive get() = Color("olive") |
||||||
|
inline val orange get() = Color("orange") |
||||||
|
inline val orangered get() = Color("orangered") |
||||||
|
inline val orchid get() = Color("orchid") |
||||||
|
inline val palegoldenrod get() = Color("palegoldenrod") |
||||||
|
inline val palegreen get() = Color("palegreen") |
||||||
|
inline val paleturquoise get() = Color("paleturquoise") |
||||||
|
inline val palevioletred get() = Color("palevioletred") |
||||||
|
inline val papayawhip get() = Color("papayawhip") |
||||||
|
inline val peachpuff get() = Color("peachpuff") |
||||||
|
inline val peru get() = Color("peru") |
||||||
|
inline val pink get() = Color("pink") |
||||||
|
inline val plum get() = Color("plum") |
||||||
|
inline val powderblue get() = Color("powderblue") |
||||||
|
inline val purple get() = Color("purple") |
||||||
|
inline val rebeccapurple get() = Color("rebeccapurple") |
||||||
|
inline val red get() = Color("red") |
||||||
|
inline val rosybrown get() = Color("rosybrown") |
||||||
|
inline val royalblue get() = Color("royalblue") |
||||||
|
inline val saddlebrown get() = Color("saddlebrown") |
||||||
|
inline val salmon get() = Color("salmon") |
||||||
|
inline val sandybrown get() = Color("sandybrown") |
||||||
|
inline val seagreen get() = Color("seagreen") |
||||||
|
inline val seashell get() = Color("seashell") |
||||||
|
inline val sienna get() = Color("sienna") |
||||||
|
inline val silver get() = Color("silver") |
||||||
|
inline val skyblue get() = Color("skyblue") |
||||||
|
inline val slateblue get() = Color("slateblue") |
||||||
|
inline val slategray get() = Color("slategray") |
||||||
|
inline val snow get() = Color("snow") |
||||||
|
inline val springgreen get() = Color("springgreen") |
||||||
|
inline val steelblue get() = Color("steelblue") |
||||||
|
inline val teal get() = Color("teal") |
||||||
|
inline val thistle get() = Color("thistle") |
||||||
|
inline val tomato get() = Color("tomato") |
||||||
|
inline val turquoise get() = Color("turquoise") |
||||||
|
inline val violet get() = Color("violet") |
||||||
|
inline val wheat get() = Color("wheat") |
||||||
|
inline val white get() = Color("white") |
||||||
|
inline val whitesmoke get() = Color("whitesmoke") |
||||||
|
inline val yellowgreen get() = Color("yellowgreen") |
||||||
|
inline val yellow get() = Color("yellow") |
||||||
|
|
||||||
|
inline val transparent get() = Color("transparent") |
||||||
|
inline val currentColor get() = Color("currentColor") |
||||||
|
} |
||||||
|
|
||||||
|
fun Color(name: String): CSSColorValue = name.unsafeCast<CSSColorValue>() |
||||||
|
|
||||||
|
private class RGB(val r: Number, val g: Number, val b: Number): CSSColorValue { |
||||||
|
override fun toString(): String = "rgb($r, $g, $b)" |
||||||
|
} |
||||||
|
|
||||||
|
private class RGBA(val r: Number, val g: Number, val b: Number, val a: Number) : CSSColorValue { |
||||||
|
override fun toString(): String = "rgba($r, $g, $b, $a)" |
||||||
|
} |
||||||
|
|
||||||
|
private class HSL(val h: CSSAngleValue, val s: Number, val l: Number) : CSSColorValue { |
||||||
|
override fun toString(): String = "hsl($h, $s%, $l%)" |
||||||
|
} |
||||||
|
|
||||||
|
private class HSLA(val h: CSSAngleValue, val s: Number, val l: Number, val a: Number) : CSSColorValue { |
||||||
|
override fun toString(): String = "hsla($h, $s%, $l%, $a)" |
||||||
|
} |
||||||
|
|
||||||
|
fun rgb(r: Number, g: Number, b: Number): CSSColorValue = RGB(r, g, b) |
||||||
|
fun rgba(r: Number, g: Number, b: Number, a: Number): CSSColorValue = RGBA(r, g, b, a) |
||||||
|
fun hsl(h: CSSAngleValue, s: Number, l: Number): CSSColorValue = HSL(h, s, l) |
||||||
|
fun hsl(h: Number, s: Number, l: Number): CSSColorValue = HSL(h.deg, s, l) |
||||||
|
fun hsla(h: CSSAngleValue, s: Number, l: Number, a: Number): CSSColorValue = HSLA(h, s, l, a) |
||||||
|
fun hsla(h: Number, s: Number, l: Number, a: Number): CSSColorValue = HSLA(h.deg, s, l, a) |
@ -0,0 +1,23 @@ |
|||||||
|
/* |
||||||
|
* 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("UNUSED", "NOTHING_TO_INLINE", "FunctionName") |
||||||
|
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.* |
||||||
|
|
||||||
|
expect interface StylePropertyValue |
||||||
|
|
||||||
|
expect interface StylePropertyNumber: StylePropertyValue |
||||||
|
expect interface StylePropertyString: StylePropertyValue |
||||||
|
|
||||||
|
inline fun StylePropertyValue(value: String): StylePropertyString = value.unsafeCast<StylePropertyString>() |
||||||
|
inline fun StylePropertyValue(value: Number): StylePropertyNumber = value.unsafeCast<StylePropertyNumber>() |
||||||
|
|
||||||
|
expect interface CSSStyleValue: StylePropertyValue { |
||||||
|
actual override fun toString(): String |
||||||
|
} |
||||||
|
|
||||||
|
inline fun CSSStyleValue(value: String): CSSStyleValue = StylePropertyValue(value).unsafeCast<CSSStyleValue>() |
@ -0,0 +1,196 @@ |
|||||||
|
/* |
||||||
|
* 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 org.jetbrains.compose.web.attributes.HtmlAttrMarker |
||||||
|
import org.jetbrains.compose.web.internal.runtime.ComposeWebInternalApi |
||||||
|
import kotlin.properties.ReadOnlyProperty |
||||||
|
import org.jetbrains.compose.web.* |
||||||
|
|
||||||
|
@Deprecated( |
||||||
|
message = "Renamed to StyleScope", |
||||||
|
replaceWith = ReplaceWith("StyleScope", "org.jetbrains.compose.web.css.StyleScope") |
||||||
|
) |
||||||
|
typealias StyleBuilder = StyleScope |
||||||
|
|
||||||
|
/** |
||||||
|
* StyleScope serves for two main purposes. Passed as a builder context (in [AttrsScope]), it |
||||||
|
* makes it possible to: |
||||||
|
* 1. Add inlined css properties to the element (@see [property]) |
||||||
|
* 2. Set values to CSS variables (@see [variable]) |
||||||
|
*/ |
||||||
|
@HtmlAttrMarker |
||||||
|
interface StyleScope { |
||||||
|
/** |
||||||
|
* Adds arbitrary CSS property to the inline style of the element |
||||||
|
* @param propertyName - the name of css property as [per spec](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference) |
||||||
|
* @param value - the value, it can be either String or specialized type like [CSSNumeric] or [CSSColorValue] |
||||||
|
* |
||||||
|
* Most frequent CSS property values can be set via specialized methods, like [width], [display] etc. |
||||||
|
* |
||||||
|
* Example: |
||||||
|
* ``` |
||||||
|
* Div({ |
||||||
|
* style { |
||||||
|
* property("some-exotic-css-property", "I am a string value") |
||||||
|
* property("some-exotic-css-property-width", 5.px) |
||||||
|
* } |
||||||
|
* }) |
||||||
|
* ``` |
||||||
|
*/ |
||||||
|
fun property(propertyName: String, value: StylePropertyValue) |
||||||
|
fun variable(variableName: String, value: StylePropertyValue) |
||||||
|
|
||||||
|
fun property(propertyName: String, value: String) = property(propertyName, StylePropertyValue(value)) |
||||||
|
fun property(propertyName: String, value: Number) = property(propertyName, StylePropertyValue(value)) |
||||||
|
fun variable(variableName: String, value: String) = variable(variableName, StylePropertyValue(value)) |
||||||
|
fun variable(variableName: String, value: Number) = variable(variableName, StylePropertyValue(value)) |
||||||
|
|
||||||
|
operator fun <TValue : StylePropertyValue> CSSStyleVariable<TValue>.invoke(value: TValue) { |
||||||
|
variable(name, value.toString()) |
||||||
|
} |
||||||
|
|
||||||
|
operator fun CSSStyleVariable<StylePropertyString>.invoke(value: String) { |
||||||
|
variable(name, value) |
||||||
|
} |
||||||
|
|
||||||
|
operator fun CSSStyleVariable<StylePropertyNumber>.invoke(value: Number) { |
||||||
|
variable(name, value) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal inline fun variableValue(variableName: String, fallback: StylePropertyValue? = null) = |
||||||
|
"var(--$variableName${fallback?.let { ", $it" } ?: ""})" |
||||||
|
|
||||||
|
expect interface CSSVariableValueAs<out T : StylePropertyValue> |
||||||
|
|
||||||
|
inline fun <TValue> CSSVariableValue(value: StylePropertyValue) = |
||||||
|
value.unsafeCast<TValue>() |
||||||
|
|
||||||
|
inline fun <TValue> CSSVariableValue(value: String) = |
||||||
|
CSSVariableValue<TValue>(StylePropertyValue(value)) |
||||||
|
|
||||||
|
// after adding `variable` word `add` became ambiguous |
||||||
|
@Deprecated( |
||||||
|
"use property instead, will remove it soon", |
||||||
|
ReplaceWith("property(propertyName, value)") |
||||||
|
) |
||||||
|
fun StyleScope.add( |
||||||
|
propertyName: String, |
||||||
|
value: StylePropertyValue |
||||||
|
) = property(propertyName, value) |
||||||
|
|
||||||
|
interface CSSVariable { |
||||||
|
val name: String |
||||||
|
} |
||||||
|
|
||||||
|
class CSSStyleVariable<out TValue : StylePropertyValue>(override val name: String) : CSSVariable |
||||||
|
|
||||||
|
fun <TValue : StylePropertyValue> CSSStyleVariable<TValue>.value(fallback: TValue? = null) = |
||||||
|
CSSVariableValue<TValue>( |
||||||
|
variableValue( |
||||||
|
name, |
||||||
|
fallback |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
fun <TValue> CSSStyleVariable<TValue>.value(fallback: TValue? = null) |
||||||
|
where TValue : CSSVariableValueAs<TValue>, |
||||||
|
TValue : StylePropertyValue = |
||||||
|
CSSVariableValue<TValue>( |
||||||
|
variableValue( |
||||||
|
name, |
||||||
|
fallback |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
/** |
||||||
|
* Introduces CSS variable that can be later referred anywhere in [StyleSheet] |
||||||
|
* |
||||||
|
* Example: |
||||||
|
* ``` |
||||||
|
* object AppCSSVariables { |
||||||
|
* val width by variable<CSSUnitValue>() |
||||||
|
* val stringHeight by variable<StylePropertyString>() |
||||||
|
* val order by variable<StylePropertyNumber>() |
||||||
|
* } |
||||||
|
* |
||||||
|
* object AppStylesheet : StyleSheet() { |
||||||
|
* val classWithProperties by style { |
||||||
|
* AppCSSVariables.width(100.px) |
||||||
|
* property("width", AppCSSVariables.width.value()) |
||||||
|
* } |
||||||
|
*``` |
||||||
|
* |
||||||
|
*/ |
||||||
|
fun <TValue : StylePropertyValue> variable() = |
||||||
|
ReadOnlyProperty<Any?, CSSStyleVariable<TValue>> { _, property -> |
||||||
|
CSSStyleVariable(property.name) |
||||||
|
} |
||||||
|
|
||||||
|
interface StyleHolder { |
||||||
|
@ComposeWebInternalApi |
||||||
|
val properties: StylePropertyList |
||||||
|
@ComposeWebInternalApi |
||||||
|
val variables: StylePropertyList |
||||||
|
} |
||||||
|
|
||||||
|
@Deprecated( |
||||||
|
message = "Renamed to StyleScopeBuilder", |
||||||
|
replaceWith = ReplaceWith("StyleScopeBuilder", "org.jetbrains.compose.web.css.StyleScopeBuilder") |
||||||
|
) |
||||||
|
typealias StyleBuilderImpl = StyleScopeBuilder |
||||||
|
|
||||||
|
@Suppress("EqualsOrHashCode") |
||||||
|
open class StyleScopeBuilder : StyleScope, 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 |
||||||
|
} |
||||||
|
|
||||||
|
@ComposeWebInternalApi |
||||||
|
internal fun copyFrom(sb: StyleHolder) { |
||||||
|
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> |
||||||
|
|
||||||
|
internal 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() |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.css.keywords |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.css.CSSKeywordValue |
||||||
|
import org.jetbrains.compose.web.* |
||||||
|
|
||||||
|
expect interface CSSAutoKeyword : CSSKeywordValue |
||||||
|
|
||||||
|
inline val auto: CSSAutoKeyword |
||||||
|
get() = CSSKeywordValue("auto").unsafeCast<CSSAutoKeyword>() |
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue