From 0a90ae219488ffbb89759fa9bc9c008d9ce5f4b6 Mon Sep 17 00:00:00 2001 From: Abasov Akif Date: Fri, 18 Jun 2021 14:11:01 +0300 Subject: [PATCH] Remove CSS Typed OM API (#786) --- .../kotlin/com/sample/components/Layout.kt | 3 - .../com/sample/content/CodeSamplesSwitcher.kt | 1 - .../kotlin/com/sample/content/CodeSnippets.kt | 4 +- .../kotlin/com/sample/content/Footer.kt | 2 - .../kotlin/com/sample/content/Header.kt | 2 - .../kotlin/com/sample/style/Stylesheet.kt | 2 +- web/core/build.gradle.kts | 1 - .../kotlin/androidx/compose/web/DomApplier.kt | 3 +- .../androidx/compose/web/css/BrowserAPI.kt | 38 +++ .../kotlin/androidx/compose/web/css/CSS.kt | 299 ------------------ .../androidx/compose/web/css/CSSEnums.kt | 183 +++++++++++ .../androidx/compose/web/css/CSSHelpers.kt | 15 - .../androidx/compose/web/css/CSSKeywords.kt | 12 + .../androidx/compose/web/css/CSSMediaRule.kt | 6 +- .../androidx/compose/web/css/CSSOperations.kt | 14 + .../androidx/compose/web/css/CSSPolyfill.kt | 15 - .../androidx/compose/web/css/CSSProperties.kt | 219 +++---------- .../androidx/compose/web/css/CSSUnits.kt | 259 ++++++++------- .../kotlin/androidx/compose/web/css/Color.kt | 15 +- .../androidx/compose/web/css/StyleBuilder.kt | 87 +++-- .../compose/web/css/StylePropertyValue.kt | 27 ++ .../compose/web/css/keywords/Keywords.kt | 14 + .../compose/web/css/selectors/CSSSelectors.kt | 2 + .../androidx/compose/web/elements/Style.kt | 8 +- web/core/src/jsTest/kotlin/CSSEnums.kt | 116 +++++++ .../src/jsTest/kotlin/CSSStylesheetTests.kt | 4 +- web/core/src/jsTest/kotlin/CSSUnitApiTests.kt | 48 +-- .../src/jsTest/kotlin/InlineStyleTests.kt | 1 + .../jsTest/kotlin/StaticComposableTests.kt | 27 +- .../androidx/compose/web/sample/Sample.kt | 24 +- web/widgets/src/jsMain/kotlin/Modifier.kt | 1 - 31 files changed, 675 insertions(+), 777 deletions(-) create mode 100644 web/core/src/jsMain/kotlin/androidx/compose/web/css/BrowserAPI.kt delete mode 100644 web/core/src/jsMain/kotlin/androidx/compose/web/css/CSS.kt create mode 100644 web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSEnums.kt delete mode 100644 web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSHelpers.kt create mode 100644 web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSKeywords.kt create mode 100644 web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSOperations.kt delete mode 100644 web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSPolyfill.kt create mode 100644 web/core/src/jsMain/kotlin/androidx/compose/web/css/StylePropertyValue.kt create mode 100644 web/core/src/jsMain/kotlin/androidx/compose/web/css/keywords/Keywords.kt create mode 100644 web/core/src/jsTest/kotlin/CSSEnums.kt diff --git a/web/benchmark-core/src/jsMain/kotlin/com/sample/components/Layout.kt b/web/benchmark-core/src/jsMain/kotlin/com/sample/components/Layout.kt index 2d54b6dac5..79475a7209 100644 --- a/web/benchmark-core/src/jsMain/kotlin/com/sample/components/Layout.kt +++ b/web/benchmark-core/src/jsMain/kotlin/com/sample/components/Layout.kt @@ -2,10 +2,7 @@ package com.sample.components import androidx.compose.runtime.Composable import org.jetbrains.compose.web.css.* -import org.jetbrains.compose.web.css.selectors.* -import org.jetbrains.compose.web.attributes.* import org.jetbrains.compose.web.dom.* -import org.jetbrains.compose.web.* import com.sample.style.WtContainer import com.sample.style.WtOffsets import com.sample.style.WtSections diff --git a/web/benchmark-core/src/jsMain/kotlin/com/sample/content/CodeSamplesSwitcher.kt b/web/benchmark-core/src/jsMain/kotlin/com/sample/content/CodeSamplesSwitcher.kt index b5f8a51897..267ee2b4bb 100644 --- a/web/benchmark-core/src/jsMain/kotlin/com/sample/content/CodeSamplesSwitcher.kt +++ b/web/benchmark-core/src/jsMain/kotlin/com/sample/content/CodeSamplesSwitcher.kt @@ -5,7 +5,6 @@ import org.jetbrains.compose.web.css.* import org.jetbrains.compose.web.css.selectors.* import org.jetbrains.compose.web.attributes.* import org.jetbrains.compose.web.dom.* -import org.jetbrains.compose.web.* import com.sample.style.AppStylesheet private object SwitcherVariables : CSSVariables { diff --git a/web/benchmark-core/src/jsMain/kotlin/com/sample/content/CodeSnippets.kt b/web/benchmark-core/src/jsMain/kotlin/com/sample/content/CodeSnippets.kt index 9c2db63100..931008a112 100644 --- a/web/benchmark-core/src/jsMain/kotlin/com/sample/content/CodeSnippets.kt +++ b/web/benchmark-core/src/jsMain/kotlin/com/sample/content/CodeSnippets.kt @@ -5,13 +5,11 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.runtime.mutableStateOf import org.jetbrains.compose.web.css.* -import org.jetbrains.compose.web.css.selectors.* -import org.jetbrains.compose.web.attributes.* import org.jetbrains.compose.web.dom.* -import org.jetbrains.compose.web.* import com.sample.HighlightJs import com.sample.components.ContainerInSection import com.sample.style.* +import org.jetbrains.compose.web.css.keywords.auto import org.w3c.dom.HTMLElement private fun HTMLElement.setHighlightedCode(code: String) { diff --git a/web/benchmark-core/src/jsMain/kotlin/com/sample/content/Footer.kt b/web/benchmark-core/src/jsMain/kotlin/com/sample/content/Footer.kt index 759c8a512e..30c37f0b23 100644 --- a/web/benchmark-core/src/jsMain/kotlin/com/sample/content/Footer.kt +++ b/web/benchmark-core/src/jsMain/kotlin/com/sample/content/Footer.kt @@ -2,10 +2,8 @@ package com.sample.content import androidx.compose.runtime.Composable import org.jetbrains.compose.web.css.* -import org.jetbrains.compose.web.css.selectors.* import org.jetbrains.compose.web.attributes.* import org.jetbrains.compose.web.dom.* -import org.jetbrains.compose.web.* import com.sample.style.* diff --git a/web/benchmark-core/src/jsMain/kotlin/com/sample/content/Header.kt b/web/benchmark-core/src/jsMain/kotlin/com/sample/content/Header.kt index edbb943b9b..f0f02f1060 100644 --- a/web/benchmark-core/src/jsMain/kotlin/com/sample/content/Header.kt +++ b/web/benchmark-core/src/jsMain/kotlin/com/sample/content/Header.kt @@ -2,10 +2,8 @@ package com.sample.content import androidx.compose.runtime.Composable import org.jetbrains.compose.web.css.* -import org.jetbrains.compose.web.css.selectors.* import org.jetbrains.compose.web.attributes.* import org.jetbrains.compose.web.dom.* -import org.jetbrains.compose.web.* import com.sample.style.* import kotlinx.browser.window diff --git a/web/benchmark-core/src/jsMain/kotlin/com/sample/style/Stylesheet.kt b/web/benchmark-core/src/jsMain/kotlin/com/sample/style/Stylesheet.kt index 909ac35d08..17c147f64d 100644 --- a/web/benchmark-core/src/jsMain/kotlin/com/sample/style/Stylesheet.kt +++ b/web/benchmark-core/src/jsMain/kotlin/com/sample/style/Stylesheet.kt @@ -20,7 +20,7 @@ object AppCSSVariables : CSSVariables { val wtH3FontSize by variable() val wtH3LineHeight by variable() - val wtColCount by variable() + val wtColCount by variable() } diff --git a/web/core/build.gradle.kts b/web/core/build.gradle.kts index 31ea84286c..f4659e50fa 100644 --- a/web/core/build.gradle.kts +++ b/web/core/build.gradle.kts @@ -31,7 +31,6 @@ kotlin { val jsMain by getting { dependencies { implementation(kotlin("stdlib-js")) - implementation(npm("css-typed-om", "0.4.0")) } } diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/DomApplier.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/DomApplier.kt index 29591f8679..4be7a3d7d9 100644 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/DomApplier.kt +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/DomApplier.kt @@ -3,7 +3,6 @@ package org.jetbrains.compose.web import androidx.compose.runtime.AbstractApplier import org.jetbrains.compose.web.attributes.WrappedEventListener import org.jetbrains.compose.web.css.StyleHolder -import org.jetbrains.compose.web.css.attributeStyleMap import org.jetbrains.compose.web.dom.setProperty import org.jetbrains.compose.web.dom.setVariable import kotlinx.browser.document @@ -109,7 +108,7 @@ class DomElementWrapper(override val node: HTMLElement): DomNodeWrapper(node) { node.removeAttribute("style") style?.properties?.forEach { (name, value) -> - setProperty(node.attributeStyleMap, name, value) + setProperty(node.style, name, value) } style?.variables?.forEach { (name, value) -> setVariable(node.style, name, value) diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/BrowserAPI.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/BrowserAPI.kt new file mode 100644 index 0000000000..2ba67589af --- /dev/null +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/BrowserAPI.kt @@ -0,0 +1,38 @@ +/* + * 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.w3c.dom.css.* +import org.w3c.dom.css.StyleSheet + +inline val StyleSheet.cssRules + get() = this.asDynamic().cssRules.unsafeCast() + + +inline fun StyleSheet.deleteRule(index: Int) { + this.asDynamic().deleteRule(index) +} + +fun StyleSheet.insertRule(cssRule: String, index: Int? = null): Int { + return if (index != null) { + this.asDynamic().insertRule(cssRule, index).unsafeCast() + } else { + this.asDynamic().insertRule(cssRule).unsafeCast() + } +} + + +inline operator fun CSSRuleList.get(index: Int): CSSRule { + return this.asDynamic()[index].unsafeCast() +} + +@Suppress("NOTHING_TO_INLINE") +inline fun jsObject(): T = + js("({})") + +inline fun jsObject(builder: T.() -> Unit): T = + jsObject().apply(builder) diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSS.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSS.kt deleted file mode 100644 index 6de379f1bf..0000000000 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSS.kt +++ /dev/null @@ -1,299 +0,0 @@ -@file:Suppress("UNUSED", "NOTHING_TO_INLINE") -package org.jetbrains.compose.web.css - -import kotlinx.browser.window -import org.w3c.dom.DOMMatrix -import org.w3c.dom.DOMMatrixReadOnly -import org.w3c.dom.Element -import org.w3c.dom.css.CSSRule -import org.w3c.dom.css.CSSRuleList -import org.w3c.dom.css.CSSStyleRule -import org.w3c.dom.css.ElementCSSInlineStyle -import org.w3c.dom.css.StyleSheet - -inline val StyleSheet.cssRules - get() = this.asDynamic().cssRules.unsafeCast() - -inline fun StyleSheet.deleteRule(index: Int) { - this.asDynamic().deleteRule(index) -} - -inline val CSSStyleRule.styleMap - get() = this.asDynamic().styleMap.unsafeCast() - -inline operator fun CSSRuleList.get(index: Int): CSSRule { - return this.asDynamic()[index].unsafeCast() -} - -fun StyleSheet.insertRule(cssRule: String, index: Int? = null): Int { - return if (index != null) { - this.asDynamic().insertRule(cssRule, index).unsafeCast() - } else { - this.asDynamic().insertRule(cssRule).unsafeCast() - } -} - -val ElementCSSInlineStyle.attributeStyleMap - get() = this.asDynamic().attributeStyleMap.unsafeCast() - -external interface CSSStyleValue : StylePropertyValue - -@JsName("CSSStyleValue") -open external class CSSStyleValueJS : CSSStyleValue { - companion object { - fun parse(property: String, cssText: String): CSSStyleValue - fun parseAll(property: String, cssText: String): Array - } -} - -external class CSSVariableReferenceValue( - variable: String, - fallback: CSSUnparsedValue? = definedExternally -) { - val variable: String - val fallback: CSSUnparsedValue? -} - -// type CSSUnparsedSegment = String | CSSVariableReferenceValue -interface CSSUnparsedSegment { - companion object { - operator fun invoke(value: String) = value.unsafeCast() - operator fun invoke(value: CSSVariableReferenceValue) = - value.unsafeCast() - } -} - -fun CSSUnparsedSegment.asString() = this.asDynamic() as? String -fun CSSUnparsedSegment.asCSSVariableReferenceValue() = - this.asDynamic() as? CSSVariableReferenceValue - -external class CSSUnparsedValue(members: Array) : CSSStyleValue { - // TODO: [Symbol.iterator]() : IterableIterator - fun forEach(handler: (CSSUnparsedSegment) -> Unit) - val length: Int - - // readonly [index: number]: CSSUnparsedSegment - operator fun get(index: Int): CSSUnparsedSegment - operator fun set(index: Int, value: CSSUnparsedSegment) -} - -// type CSSNumberish = number | CSSNumericValue -interface CSSNumberish { - companion object { - operator fun invoke(value: Number) = value.unsafeCast() - operator fun invoke(value: CSSNumericValue) = - value.unsafeCast() - } -} - -fun CSSNumberish.asNumber() = this.asDynamic() as? Number -fun CSSNumberish.asCSSNumericValue(): CSSNumericValue? = this.asDynamic() as? CSSNumericValue - -// declare enum CSSNumericBaseType { -// 'length', -// 'angle', -// 'time', -// 'frequency', -// 'resolution', -// 'flex', -// 'percent', -// } -enum class CSSNumericBaseType(val value: String) { - @JsName("_length") - length("length"), - angle("angle"), - time("time"), - frequency("frequency"), - resolution("resolution"), - flex("flex"), - percent("percent") -} - -external interface CSSNumericType { - val length: Number - val angle: Number - val time: Number - val frequency: Number - val resolution: Number - val flex: Number - val percent: Number - // percentHint: CSSNumericBaseType -} - -val CSSNumericType.percentHint - get() = CSSNumericBaseType.valueOf(this.asDynamic().percentHint) -// set(value) { this.asDynamic().percentHint = value.value } - -external interface CSSNumericValue : CSSStyleValue - -// declare enum CSSMathOperator { -// 'sum', -// 'product', -// 'negate', -// 'invert', -// 'min', -// 'max', -// 'clamp', -// } -enum class CSSMathOperator(val value: String) { - sum("sum"), - product("product"), - negate("negate"), - invert("invert"), - min("min"), - max("max"), - clamp("clamp") -} - -open external class CSSMathValue : CSSNumericValue - -val CSSMathValue.operator - get() = CSSMathOperator.valueOf(this.asDynamic().operator) -// set(value) { this.asDynamic().operator = value.value } - -external class CSSMathSum(vararg args: CSSNumberish) : CSSMathValue { - val values: CSSNumericArray -} - -external class CSSMathProduct(vararg args: CSSNumberish) : CSSMathValue { - val values: CSSNumericArray -} - -external class CSSMathNegate(arg: CSSNumberish) : CSSMathValue { - val value: CSSNumericValue -} - -external class CSSMathInvert(arg: CSSNumberish) : CSSMathValue { - val value: CSSNumericValue -} - -external class CSSMathMin(vararg args: CSSNumberish) : CSSMathValue { - val values: CSSNumericArray -} - -external class CSSMathMax(vararg args: CSSNumberish) : CSSMathValue { - val values: CSSNumericArray -} - -external class CSSNumericArray { - // TODO: [Symbol.iterator]() : IterableIterator - fun forEach(handler: (CSSNumericValue) -> Unit) - val length: Int - - // readonly [index: number]: CSSNumericValue - operator fun get(index: Int): CSSNumericValue -} - -external class CSSTransformValue(transforms: Array) : CSSStyleValue { - // [Symbol.iterator]() : IterableIterator - fun forEach(handler: (CSSTransformComponent) -> Unit) - val length: Int - - // [index: number]: CSSTransformComponent - operator fun get(index: Int): CSSTransformComponent - operator fun set(index: Int, value: CSSTransformComponent) - val is2D: Boolean - fun toMatrix(): DOMMatrix -} - -open external class CSSTransformComponent { - val is2D: Boolean - fun toMatrix(): DOMMatrix - // toString() : string -} - -external class CSSTranslate( - x: CSSNumericValue, - y: CSSNumericValue, - z: CSSNumericValue? = definedExternally -) : CSSTransformComponent { - val x: CSSNumericValue - val y: CSSNumericValue - val z: CSSNumericValue -} - -external class CSSRotate(angle: CSSNumericValue) : CSSTransformComponent { - constructor(x: CSSNumberish, y: CSSNumberish, z: CSSNumberish, angle: CSSNumericValue) - - val x: CSSNumberish - val y: CSSNumberish - val z: CSSNumberish - val angle: CSSNumericValue -} - -external class CSSScale( - x: CSSNumberish, - y: CSSNumberish, - z: CSSNumberish? = definedExternally -) : CSSTransformComponent { - val x: CSSNumberish - val y: CSSNumberish - val z: CSSNumberish -} - -external class CSSSkew(ax: CSSNumericValue, ay: CSSNumericValue) : CSSTransformComponent { - val ax: CSSNumericValue - val ay: CSSNumericValue -} - -external class CSSSkewX(ax: CSSNumericValue) : CSSTransformComponent { - val ax: CSSNumericValue -} - -external class CSSSkewY(ay: CSSNumericValue) : CSSTransformComponent { - val ay: CSSNumericValue -} - -/* Note that skew(x,y) is *not* the same as skewX(x) skewY(y), - thus the separate interfaces for all three. */ - -external class CSSPerspective(length: CSSNumericValue) : CSSTransformComponent { - val length: CSSNumericValue -} - -external class CSSMatrixComponent( - matrix: DOMMatrixReadOnly, - options: CSSMatrixComponentOptions? = definedExternally -) : CSSTransformComponent { - val matrix: DOMMatrix -} - -external interface CSSMatrixComponentOptions { - val is2D: Boolean -} - -external class CSSImageValue : CSSStyleValue - -open external class StylePropertyMapReadOnly { - // TODO: [Symbol.iterator]() : IterableIterator<[string, CSSStyleValue[]]> - - fun get(property: String): CSSStyleValue? // CSSStyleValue | undefined - fun getAll(property: String): Array - fun has(property: String): Boolean - val size: Number -} - -fun StylePropertyMapReadOnly.forEach(handler: (String, Array) -> Unit) { - this.asDynamic().forEach { entry: Array -> - handler( - entry[0].unsafeCast(), - entry[1].unsafeCast>() - ) - } -} - -// CSSStyleValue | string -external interface StylePropertyValue - -external class StylePropertyMap : StylePropertyMapReadOnly { - fun set(property: String, vararg values: StylePropertyValue) - fun append(property: String, vararg values: StylePropertyValue) - fun delete(property: String) - fun clear() -} - -inline fun Element.computedStyleMap(): StylePropertyMapReadOnly = - this.asDynamic().computedStyleMap().unsafeCast() - -@Suppress("unused") -val cssTypedOMPolyfill = CSSTypedOMPolyfill.default(window) diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSEnums.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSEnums.kt new file mode 100644 index 0000000000..aa7b96a500 --- /dev/null +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSEnums.kt @@ -0,0 +1,183 @@ +@file:Suppress("Unused", "NOTHING_TO_INLINE", "NESTED_CLASS_IN_EXTERNAL_INTERFACE", "INLINE_EXTERNAL_DECLARATION", "WRONG_BODY_OF_EXTERNAL_DECLARATION", "NESTED_EXTERNAL_DECLARATION") + +package org.jetbrains.compose.web.css + +external interface StylePropertyEnum: StylePropertyString +inline val StylePropertyEnum.name get() = this.unsafeCast() +inline val StylePropertyEnum.value get() = this.unsafeCast() + +external interface LineStyle: StylePropertyEnum { + external companion object { + inline val None get() = LineStyle("none") + inline val Hidden get() = LineStyle("hidden") + inline val Dotted get() = LineStyle("dotted") + inline val Dashed get() = LineStyle("dashed") + inline val Solid get() = LineStyle("solid") + inline val Double get() = LineStyle("double") + inline val Groove get() = LineStyle("groove") + inline val Ridge get() = LineStyle("ridge") + inline val Inset get() = LineStyle("inset") + inline val Outset get() = LineStyle("outset") + } +} +inline fun LineStyle(value: String) = value.unsafeCast() + +external interface DisplayStyle: StylePropertyEnum { + external companion object { + inline val Block get() = DisplayStyle("block") + inline val Inline get() = DisplayStyle("inline") + inline val InlineBlock get() = DisplayStyle("inline-block") + inline val Flex get() = DisplayStyle("flex") + inline val LegacyInlineFlex get() = DisplayStyle("inline-flex") + inline val Grid get() = DisplayStyle("grid") + inline val LegacyInlineGrid get() = DisplayStyle("inline-grid") + inline val FlowRoot get() = DisplayStyle("flow-root") + + inline val None get() = DisplayStyle("none") + inline val Contents get() = DisplayStyle("contents") + +// TODO(shabunc): This properties behave them iconsistenly in both Chrome and Firefox so I turned the off so far +// BlockFlow("block flow") +// InlineFlow("inline flow") +// InlineFlowRoot("inline flow-root") +// BlocklFlex("block flex") +// InlineFlex("inline flex") +// BlockGrid("block grid") +// InlineGrid("inline grid") +// BlockFlowRoot("block flow-root") + + inline val Table get() = DisplayStyle("table") + inline val TableRow get() = DisplayStyle("table-row") + inline val ListItem get() = DisplayStyle("list-item") + + inline val Inherit get() = DisplayStyle("inherit") + inline val Initial get() = DisplayStyle("initial") + inline val Unset get() = DisplayStyle("unset") + } +} +inline fun DisplayStyle(value: String) = value.unsafeCast() + +external interface FlexDirection: StylePropertyEnum { + companion object { + inline val Row get() = FlexDirection("row") + inline val RowReverse get() = FlexDirection("row-reverse") + inline val Column get() = FlexDirection("column") + inline val ColumnReverse get() = FlexDirection("column-reverse") + } +} +inline fun FlexDirection(value: String) = value.unsafeCast() + +external interface FlexWrap: StylePropertyEnum { + companion object { + inline val Wrap get() = FlexWrap("wrap") + inline val Nowrap get() = FlexWrap("nowrap") + inline val WrapReverse get() = FlexWrap("wrap-reverse") + } +} +inline fun FlexWrap(value: String) = value.unsafeCast() + +external interface JustifyContent: StylePropertyEnum { + companion object { + inline val Center get() = JustifyContent("center") + inline val Start get() = JustifyContent("start") + inline val End get() = JustifyContent("end") + inline val FlexStart get() = JustifyContent("flex-start") + inline val FlexEnd get() = JustifyContent("flex-end") + inline val Left get() = JustifyContent("left") + inline val Right get() = JustifyContent("right") + inline val Normal get() = JustifyContent("normal") + inline val SpaceBetween get() = JustifyContent("space-between") + inline val SpaceAround get() = JustifyContent("space-around") + inline val SpaceEvenly get() = JustifyContent("space-evenly") + inline val Stretch get() = JustifyContent("stretch") + inline val Inherit get() = JustifyContent("inherit") + inline val Initial get() = JustifyContent("initial") + inline val Unset get() = JustifyContent("unset") + inline val SafeCenter get() = JustifyContent("safe center") + inline val UnsafeCenter get() = JustifyContent("unsafe center") + } +} +inline fun JustifyContent(value: String) = value.unsafeCast() + +external interface AlignSelf: StylePropertyEnum { + companion object { + inline val Auto get() = AlignSelf("auto") + inline val Normal get() = AlignSelf("normal") + inline val Center get() = AlignSelf("center") + inline val Start get() = AlignSelf("start") + inline val End get() = AlignSelf("end") + inline val SelfStart get() = AlignSelf("self-start") + inline val SelfEnd get() = AlignSelf("self-end") + inline val FlexStart get() = AlignSelf("flex-start") + inline val FlexEnd get() = AlignSelf("flex-end") + inline val Baseline get() = AlignSelf("baseline") +// FirstBaseline("first baseline") +// LastBaseline("last baseline") + inline val Stretch get() = AlignSelf("stretch") + inline val SafeCenter get() = AlignSelf("safe center") + inline val UnsafeCenter get() = AlignSelf("unsafe center") + inline val Inherit get() = AlignSelf("inherit") + inline val Initial get() = AlignSelf("initial") + inline val Unset get() = AlignSelf("unset") + } +} +inline fun AlignSelf(value: String) = value.unsafeCast() + +external interface AlignItems: StylePropertyEnum { + companion object { + inline val Normal get() = AlignItems("normal") + inline val Stretch get() = AlignItems("stretch") + inline val Center get() = AlignItems("center") + inline val Start get() = AlignItems("start") + inline val End get() = AlignItems("end") + inline val FlexStart get() = AlignItems("flex-start") + inline val FlexEnd get() = AlignItems("flex-end") + inline val Baseline get() = AlignItems("baseline") +// FirstBaseline("first baseline") +// LastBaseline("last baseline") + inline val SafeCenter get() = AlignItems("safe center") + inline val UnsafeCenter get() = AlignItems("unsafe center") + + inline val Inherit get() = AlignItems("inherit") + inline val Initial get() = AlignItems("initial") + inline val Unset get() = AlignItems("unset") + } +} +inline fun AlignItems(value: String) = value.unsafeCast() + +external interface AlignContent: StylePropertyEnum { + companion object { + inline val Center get() = AlignContent("center") + inline val Start get() = AlignContent("start") + inline val End get() = AlignContent("end") + inline val FlexStart get() = AlignContent("flex-start") + inline val FlexEnd get() = AlignContent("flex-end") + inline val Baseline get() = AlignContent("baseline") +// FirstBaseline("first baseline") +// LastBaseline("last baseline") + inline val SafeCenter get() = AlignContent("safe center") + inline val UnsafeCenter get() = AlignContent("unsafe center") + inline val SpaceBetween get() = AlignContent("space-between") + inline val SpaceAround get() = AlignContent("space-around") + inline val SpaceEvenly get() = AlignContent("space-evenly") + inline val Stretch get() = AlignContent("stretch") + + inline val Inherit get() = AlignContent("inherit") + inline val Initial get() = AlignContent("initial") + inline val Unset get() = AlignContent("unset") + } +} +inline fun AlignContent(value: String) = value.unsafeCast() + +external interface Position: StylePropertyEnum { + companion object { + inline val Static get() = Position("static") + inline val Relative get() = Position("relative") + inline val Absolute get() = Position("absolute") + inline val Sticky get() = Position("sticky") + inline val Fixed get() = Position("fixed") + } +} +inline fun Position(value: String) = value.unsafeCast() + +typealias LanguageCode = String diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSHelpers.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSHelpers.kt deleted file mode 100644 index 24c0873d76..0000000000 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSHelpers.kt +++ /dev/null @@ -1,15 +0,0 @@ -@file:Suppress("UNUSED") -package org.jetbrains.compose.web.css - -interface CSSAutoValue : StylePropertyValue - -val auto = "auto".unsafeCast() - -enum class Direction { - rtl, - ltr; - - override fun toString(): String = this.name -} - -typealias LanguageCode = String diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSKeywords.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSKeywords.kt new file mode 100644 index 0000000000..eb8cef1b02 --- /dev/null +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSKeywords.kt @@ -0,0 +1,12 @@ +/* + * 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 + +external interface CSSKeywordValue : CSSStyleValue + +inline fun CSSKeywordValue(value: String): CSSKeywordValue = CSSStyleValue(value).unsafeCast() diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSMediaRule.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSMediaRule.kt index 7b004b83c6..b25d447dd4 100644 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSMediaRule.kt +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSMediaRule.kt @@ -1,3 +1,5 @@ +@file:Suppress("unused", "MemberVisibilityCanBePrivate") + package org.jetbrains.compose.web.css interface CSSMediaQuery { @@ -9,12 +11,13 @@ interface CSSMediaQuery { } data class MediaType(val type: Enum) : Atomic { enum class Enum { - all, print, screen, speech + All, Print, Screen, Speech } override fun toString() = type.name } + @Suppress("EqualsOrHashCode") data class MediaFeature( val name: String, val value: StylePropertyValue? = null @@ -55,6 +58,7 @@ interface CSSMediaQuery { } } +@Suppress("EqualsOrHashCode") class CSSMediaRuleDeclaration( val query: CSSMediaQuery, rules: CSSRuleDeclarationList diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSOperations.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSOperations.kt new file mode 100644 index 0000000000..b131ca1768 --- /dev/null +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSOperations.kt @@ -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. + */ + +package org.jetbrains.compose.web.css + +operator fun CSSSizeValue.times(num: Number): CSSSizeValue = CSSUnitValueTyped(value * num.toFloat(), unit) +operator fun Number.times(unit: CSSSizeValue): CSSSizeValue = CSSUnitValueTyped(unit.value * toFloat(), unit.unit) + +operator fun CSSSizeValue.div(num: Number): CSSSizeValue = CSSUnitValueTyped(value / num.toFloat(), unit) + +operator fun CSSSizeValue.plus(b: CSSSizeValue): CSSSizeValue = CSSUnitValueTyped(value + b.value, unit) +operator fun CSSSizeValue.minus(b: CSSSizeValue): CSSSizeValue = CSSUnitValueTyped(value - b.value, unit) \ No newline at end of file diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSPolyfill.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSPolyfill.kt deleted file mode 100644 index 21b11dbf21..0000000000 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSPolyfill.kt +++ /dev/null @@ -1,15 +0,0 @@ -package org.jetbrains.compose.web.css - -import org.w3c.dom.Window - -@JsModule("css-typed-om") -@JsNonModule -abstract external class CSSTypedOMPolyfill { - companion object { - fun default(window: Window) - } -} - -fun StylePropertyMap.clear() { - throw AssertionError("StylePropertyMap::clear isn't polyfilled") -} diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSProperties.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSProperties.kt index 2b682ceeb1..74fc979379 100644 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSProperties.kt +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSProperties.kt @@ -1,5 +1,9 @@ +@file:Suppress("Unused", "NOTHING_TO_INLINE") + package org.jetbrains.compose.web.css +import org.jetbrains.compose.web.css.keywords.CSSAutoKeyword + fun StyleBuilder.opacity(value: Number) { property("opacity", value) } @@ -17,7 +21,7 @@ fun StyleBuilder.flexShrink(value: Number) { } fun StyleBuilder.opacity(value: CSSSizeValue) { - property("opacity", (value.value as Double / 100)) + property("opacity", (value.value / 100)) } fun StyleBuilder.color(value: String) { @@ -26,7 +30,7 @@ fun StyleBuilder.color(value: String) { fun StyleBuilder.color(value: Color) { // color hasn't Typed OM yet - property("color", value.styleValue()) + property("color", value) } fun StyleBuilder.backgroundColor(value: CSSVariableValue) { @@ -34,196 +38,49 @@ fun StyleBuilder.backgroundColor(value: CSSVariableValue) { } fun StyleBuilder.backgroundColor(value: Color) { - property("background-color", value.styleValue()) + property("background-color", value) } fun StyleBuilder.backgroundColor(value: String) { property("background-color", value) } -enum class LineStyle { - None, - Hidden, - Dotted, - Dashed, - Solid, - Double, - Groove, - Ridge, - Inset, - Outset -} - -enum class DisplayStyle(val value: String) { - Block("block"), - Inline("inline"), - InlineBlock("inline-block"), - Flex("flex"), - LegacyInlineFlex("inline-flex"), - Grid("grid"), - LegacyInlineGrid("inline-grid"), - FlowRoot("flow-root"), - - None("none"), - Contents("contents"), - -// TODO(shabunc): This properties behave them iconsistenly in both Chrome and Firefox so I turned the off so far -// BlockFlow("block flow"), -// InlineFlow("inline flow"), -// InlineFlowRoot("inline flow-root"), -// BlocklFlex("block flex"), -// InlineFlex("inline flex"), -// BlockGrid("block grid"), -// InlineGrid("inline grid"), -// BlockFlowRoot("block flow-root"), - - Table("table"), - TableRow("table-row"), - ListItem("list-item"), - - Inherit("inherit"), - Initial("initial"), - Unset("unset") -} - -enum class FlexDirection(val value: String) { - Row("row"), - RowReverse("row-reverse"), - Column("column"), - ColumnReverse("column-reverse") -} - -enum class FlexWrap(val value: String) { - Wrap("wrap"), - Nowrap("nowrap"), - WrapReverse("wrap-reverse") -} - -enum class JustifyContent(val value: String) { - Center("center"), - Start("start"), - End("end"), - FlexStart("flex-start"), - FlexEnd("flex-end"), - Left("left"), - Right("right"), - Normal("normal"), - SpaceBetween("space-between"), - SpaceAround("space-around"), - SpaceEvenly("space-evenly"), - Stretch("stretch"), - Inherit("inherit"), - Initial("initial"), - Unset("unset"), - SafeCenter("safe center"), - UnsafeCenter("unsafe center"), -} - -enum class AlignSelf(val value: String) { - Auto("auto"), - Normal("normal"), - Center("center"), - Start("start"), - End("end"), - SelfStart("self-start"), - SelfEnd("self-end"), - FlexStart("flex-start"), - FlexEnd("flex-end"), - Baseline("baseline"), -// FirstBaseline("first baseline"), -// LastBaseline("last baseline"), - Stretch("stretch"), - SafeCenter("safe center"), - UnsafeCenter("unsafe center"), - Inherit("inherit"), - Initial("initial"), - Unset("unset") -} - -enum class AlignItems(val value: String) { - Normal("normal"), - Stretch("stretch"), - Center("center"), - Start("start"), - End("end"), - FlexStart("flex-start"), - FlexEnd("flex-end"), - Baseline("baseline"), -// FirstBaseline("first baseline"), -// LastBaseline("last baseline"), - SafeCenter("safe center"), - UnsafeCenter("unsafe center"), - - Inherit("inherit"), - Initial("initial"), - Unset("unset") -} - -enum class AlignContent(val value: String) { - Center("center"), - Start("start"), - End("end"), - FlexStart("flex-start"), - FlexEnd("flex-end"), - Baseline("baseline"), -// FirstBaseline("first baseline"), -// LastBaseline("last baseline"), - SafeCenter("safe center"), - UnsafeCenter("unsafe center"), - SpaceBetween("space-between"), - SpaceAround("space-around"), - SpaceEvenly("space-evenly"), - Stretch("stretch"), - - Inherit("inherit"), - Initial("initial"), - Unset("unset") -} - -enum class Position(val value: String) { - Static("static"), - Relative("relative"), - Absolute("absolute"), - Sticky("sticky"), - Fixed("fixed") -} - -class CSSBorder : CustomStyleValue { +@Suppress("EqualsOrHashCode") +class CSSBorder : CSSStyleValue { var width: CSSUnitValue? = null var style: StylePropertyValue? = null var color: StylePropertyValue? = null - fun width(size: CSSUnitValue) { - width = size + override fun equals(other: Any?): Boolean { + return if (other is CSSBorder) { + width == other.width && style == other.style && color == other.color + } else false } - fun style(style: LineStyle) { - this.style = style.name.unsafeCast() + override fun toString(): String { + val values = listOfNotNull(width, style, color) + return values.joinToString(" ") } +} - fun color(color: Color) { - this.color = color.styleValue() - } +inline fun CSSBorder.width(size: CSSUnitValue) { + width = size +} - fun color(color: CSSVariableValue) { - this.color = color - } +inline fun CSSBorder.style(style: LineStyle) { + this.style = CSSStyleValue(style.name) +} - override fun equals(other: Any?): Boolean { - return if (other is CSSBorder) { - styleValue().toString() == other.styleValue().toString() - } else false - } +inline fun CSSBorder.color(color: Color) { + this.color = color +} - override fun styleValue(): StylePropertyValue { - val values = listOfNotNull(width?.asString(), style, color) - return values.joinToString(" ").unsafeCast() - } +inline fun CSSBorder.color(color: CSSVariableValue) { + this.color = color } inline fun StyleBuilder.border(crossinline borderBuild: CSSBorder.() -> Unit) { - val border = CSSBorder().apply(borderBuild) - property("border", border.styleValue()) + property("border", CSSBorder().apply(borderBuild)) } fun StyleBuilder.border( @@ -296,7 +153,7 @@ fun StyleBuilder.borderRadius(r: CSSUnitValue) { } fun StyleBuilder.borderRadius(topLeft: CSSUnitValue, bottomRight: CSSUnitValue) { - property("border-radius", "${topLeft.asString()} ${bottomRight.asString()}") + property("border-radius", "$topLeft $bottomRight") } fun StyleBuilder.borderRadius( @@ -304,7 +161,7 @@ fun StyleBuilder.borderRadius( topRightAndBottomLeft: CSSUnitValue, bottomRight: CSSUnitValue ) { - property("border-radius", "${topLeft.asString()} ${topRightAndBottomLeft.asString()} ${bottomRight.asString()}") + property("border-radius", "$topLeft $topRightAndBottomLeft $bottomRight") } fun StyleBuilder.borderRadius( @@ -315,7 +172,7 @@ fun StyleBuilder.borderRadius( ) { property( "border-radius", - "${topLeft.asString()} ${topRight.asString()} ${bottomRight.asString()} ${bottomLeft.asString()}" + "$topLeft $topRight $bottomRight $bottomLeft" ) } @@ -323,7 +180,7 @@ fun StyleBuilder.width(value: CSSUnitValue) { property("width", value) } -fun StyleBuilder.width(value: CSSAutoValue) { +fun StyleBuilder.width(value: CSSAutoKeyword) { property("width", value) } @@ -331,7 +188,7 @@ fun StyleBuilder.height(value: CSSUnitValue) { property("height", value) } -fun StyleBuilder.height(value: CSSAutoValue) { +fun StyleBuilder.height(value: CSSAutoKeyword) { property("height", value) } @@ -339,7 +196,7 @@ fun StyleBuilder.top(value: CSSLengthOrPercentageValue) { property("top", value) } -fun StyleBuilder.top(value: CSSAutoValue) { +fun StyleBuilder.top(value: CSSAutoKeyword) { property("top", value) } @@ -347,7 +204,7 @@ fun StyleBuilder.bottom(value: CSSLengthOrPercentageValue) { property("bottom", value) } -fun StyleBuilder.bottom(value: CSSAutoValue) { +fun StyleBuilder.bottom(value: CSSAutoKeyword) { property("bottom", value) } @@ -355,7 +212,7 @@ fun StyleBuilder.left(value: CSSLengthOrPercentageValue) { property("left", value) } -fun StyleBuilder.left(value: CSSAutoValue) { +fun StyleBuilder.left(value: CSSAutoKeyword) { property("left", value) } @@ -363,7 +220,7 @@ fun StyleBuilder.right(value: CSSLengthOrPercentageValue) { property("right", value) } -fun StyleBuilder.right(value: CSSAutoValue) { +fun StyleBuilder.right(value: CSSAutoKeyword) { property("right", value) } diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSUnits.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSUnits.kt index 14b751cd1f..cad9d51b65 100644 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSUnits.kt +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/CSSUnits.kt @@ -1,180 +1,173 @@ +@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 -interface CSSSizeValue : StylePropertyValue { +external interface CSSNumericValue : StylePropertyValue + +external interface CSSSizeValue : CSSNumericValue { val value: Float val unit: T - fun asString(): String = "${value}${unit.value}" - fun newUnit(value: Float): CSSSizeValue } -private data class CSSUnitValueTyped( +data class CSSUnitValueTyped( override val value: Float, override val unit: T ) : CSSSizeValue { - override fun newUnit(value: Float): CSSSizeValue = copy(value = value) - override fun toString(): String = asString() + override fun toString(): String = "$value$unit" } -operator fun CSSSizeValue.times(num: Number): CSSSizeValue = newUnit(value * num.toFloat()) -operator fun Number.times(unit: CSSSizeValue): CSSSizeValue = unit.newUnit(unit.value * toFloat()) - -operator fun CSSSizeValue.div(num: Number): CSSSizeValue = newUnit(value / num.toFloat()) - -operator fun CSSSizeValue.plus(b: CSSSizeValue): CSSSizeValue = newUnit(value + b.value) -operator fun CSSSizeValue.minus(b: CSSSizeValue): CSSSizeValue = newUnit(value - b.value) - -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 -typealias CSSLengthOrPercentageValue = CSSSizeValue -typealias CSSLengthValue = CSSSizeValue -typealias CSSPercentageValue = CSSSizeValue -typealias CSSUnitValue = CSSSizeValue +external interface CSSUnitLengthOrPercentage: CSSUnit +external interface CSSUnitPercentage: CSSUnitLengthOrPercentage +external interface CSSUnitLength: CSSUnitLengthOrPercentage +external interface CSSUnitRel : CSSUnitLength +external interface CSSUnitAbs: CSSUnitLength +external interface CSSUnitAngle: CSSUnit +external interface CSSUnitTime: CSSUnit +external interface CSSUnitFrequency: CSSUnit +external interface CSSUnitResolution: CSSUnit +external interface CSSUnitFlex: CSSUnit + +typealias CSSAngleValue = CSSSizeValue +typealias CSSLengthOrPercentageValue = CSSSizeValue +typealias CSSLengthValue = CSSSizeValue +typealias CSSPercentageValue = CSSSizeValue +typealias CSSUnitValue = CSSSizeValue typealias CSSpxValue = CSSSizeValue +// fake interfaces to distinguish units +external interface CSSUnit { + external interface percent: CSSUnitPercentage -sealed interface CSSUnit { - val value: String + external interface em: CSSUnitRel - object percent: CSSUnitPercentage { - override val value: String = "%" - } + external interface ex: CSSUnitRel - object em: CSSUnitRel { - override val value = "em" - } + external interface ch: CSSUnitRel - object ex: CSSUnitRel { - override val value = "ex" - } + external interface ic: CSSUnitRel - object ch: CSSUnitRel { - override val value = "ch" - } + external interface rem: CSSUnitRel - object ic: CSSUnitRel { - override val value = "ic" - } + external interface lh: CSSUnitRel - object rem: CSSUnitRel { - override val value = "rem" - } + external interface rlh: CSSUnitRel - object lh: CSSUnitRel { - override val value = "lh" - } + external interface vw: CSSUnitRel - object rlh: CSSUnitRel { - override val value = "rlh" - } + external interface vh: CSSUnitRel - object vw: CSSUnitRel { - override val value = "vw" - } + external interface vi: CSSUnitRel - object vh: CSSUnitRel { - override val value = "vh" - } + external interface vb: CSSUnitRel - object vi: CSSUnitRel { - override val value = "vi" - } + external interface vmin: CSSUnitRel - object vb: CSSUnitRel { - override val value = "vb" - } + external interface vmax: CSSUnitRel - object vmin: CSSUnitRel { - override val value = "vmin" - } + external interface cm: CSSUnitRel - object vmax: CSSUnitRel { - override val value = "vmax" - } + external interface mm: CSSUnitRel - object cm: CSSUnitRel { - override val value = "cm" - } + external interface Q: CSSUnitRel - object mm: CSSUnitRel { - override val value = "mm" - } + external interface pt: CSSUnitAbs - object q: CSSUnitRel { - override val value = "q" - } + external interface pc: CSSUnitAbs - object pt: CSSUnitAbs { - override val value = "pt" - } + external interface px: CSSUnitAbs - object pc: CSSUnitAbs { - override val value = "pc" - } + external interface deg: CSSUnitAngle - object px: CSSUnitAbs { - override val value = "px" - } + external interface grad: CSSUnitAngle - object deg: CSSUnitAngle { - override val value = "deg" - } + external interface rad: CSSUnitAngle - object grad: CSSUnitAngle { - override val value = "grad" - } + external interface turn: CSSUnitAngle - object rad: CSSUnitAngle { - override val value = "rad" - } + external interface s: CSSUnitTime - object turn: CSSUnitAngle { - override val value = "turn" - } + external interface ms: CSSUnitTime - object s: CSSUnitTime { - override val value = "s" - } + external interface Hz: CSSUnitFrequency - object ms: CSSUnitTime { - override val value = "ms" - } + external interface kHz: CSSUnitFrequency - object hz: CSSUnitFrequency { - override val value = "hz" - } + external interface dpi: CSSUnitResolution - object khz: CSSUnitFrequency { - override val value = "khz" - } + external interface dpcm: CSSUnitResolution - object dpi: CSSUnitResolution { - override val value = "dpi" - } + external interface dppx: CSSUnitResolution - object dpcm: CSSUnitResolution { - override val value = "dpcm" - } + external interface fr: CSSUnitFlex - object dppx: CSSUnitResolution { - override val value = "dppx" - } + external interface number: CSSUnit + + external companion object { + inline val percent get() = "%".unsafeCast() - object fr: CSSUnitFlex { - override val value = "fr" - } + inline val em get() = "em".unsafeCast() + + inline val ex get() = "ex".unsafeCast() + + inline val ch get() = "ch".unsafeCast() + + inline val ic get() = "ic".unsafeCast() + + inline val rem get() = "rem".unsafeCast() + + inline val lh get() = "lh".unsafeCast() + + inline val rlh get() = "rlh".unsafeCast() + + inline val vw get() = "vw".unsafeCast() + + inline val vh get() = "vh".unsafeCast() + + inline val vi get() = "vi".unsafeCast() + + inline val vb get() = "vb".unsafeCast() + + inline val vmin get() = "vmin".unsafeCast() + + inline val vmax get() = "vmax".unsafeCast() + + inline val cm get() = "cm".unsafeCast() + + inline val mm get() = "mm".unsafeCast() + + inline val Q get() = "Q".unsafeCast() + + inline val pt get() = "pt".unsafeCast() + + inline val pc get() = "pc".unsafeCast() + + inline val px get() = "px".unsafeCast() + + inline val deg get() = "deg".unsafeCast() + + inline val grad get() = "grad".unsafeCast() + + inline val rad get() = "rad".unsafeCast() + + inline val turn get() = "turn".unsafeCast() + + inline val s get() = "s".unsafeCast() + + inline val ms get() = "ms".unsafeCast() + + inline val Hz get() = "Hz".unsafeCast() + + inline val kHz get() = "kHz".unsafeCast() + + inline val dpi get() = "dpi".unsafeCast() + + inline val dpcm get() = "dpcm".unsafeCast() + + inline val dppx get() = "dppx".unsafeCast() + + inline val fr get() = "fr".unsafeCast() - object number: CSSUnit { - override val value = "number" + inline val number get() = "number".unsafeCast() } } @@ -216,7 +209,7 @@ val Number.mm get(): CSSSizeValue = CSSUnitValueTyped(this.toFloat(), CSSUnit.mm) val Number.Q - get() : CSSSizeValue = CSSUnitValueTyped(this.toFloat(), CSSUnit.q) + get() : CSSSizeValue = CSSUnitValueTyped(this.toFloat(), CSSUnit.Q) val Number.pt get(): CSSSizeValue = CSSUnitValueTyped(this.toFloat(), CSSUnit.pt) @@ -240,9 +233,9 @@ val Number.ms get(): CSSSizeValue = CSSUnitValueTyped(this.toFloat(), CSSUnit.ms) val Number.Hz - get(): CSSSizeValue = CSSUnitValueTyped(this.toFloat(), CSSUnit.hz) + get(): CSSSizeValue = CSSUnitValueTyped(this.toFloat(), CSSUnit.Hz) val Number.kHz - get(): CSSSizeValue = CSSUnitValueTyped(this.toFloat(), CSSUnit.khz) + get(): CSSSizeValue = CSSUnitValueTyped(this.toFloat(), CSSUnit.kHz) val Number.dpi get(): CSSSizeValue = CSSUnitValueTyped(this.toFloat(), CSSUnit.dpi) diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/Color.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/Color.kt index 9faebab38e..03afdc81e2 100644 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/css/Color.kt +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/Color.kt @@ -1,8 +1,8 @@ -package org.jetbrains.compose.web.css +@file:Suppress("unused", "MemberVisibilityCanBePrivate") -abstract class Color : CustomStyleValue { - override fun styleValue(): StylePropertyValue = toString().unsafeCast() +package org.jetbrains.compose.web.css +abstract class Color : CSSStyleValue { data class Named(val value: String) : Color() { override fun toString(): String = value } @@ -18,16 +18,15 @@ abstract class Color : CustomStyleValue { data class HSL(val h: CSSAngleValue, val s: Number, val l: Number) : Color() { constructor(h: Number, s: Number, l: Number) : this(h.deg, s, l) - override fun toString(): String = "hsl(${h.asString()}, $s%, $l%)" + override fun toString(): String = "hsl($h, $s%, $l%)" } data class HSLA(val h: CSSAngleValue, val s: Number, val l: Number, val a: Number) : Color() { constructor(h: Number, s: Number, l: Number, a: Number) : this(h.deg, s, l, a) - override fun toString(): String = "hsla(${h.asString()}, $s%, $l%, $a)" + override fun toString(): String = "hsla($h, $s%, $l%, $a)" } - companion object { - operator fun invoke(name: String) = Named(name) - } } + +fun Color(name: String): Color = Color.Named(name) \ No newline at end of file diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/StyleBuilder.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/StyleBuilder.kt index 45dff62a94..8418c71f91 100644 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/css/StyleBuilder.kt +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/StyleBuilder.kt @@ -1,3 +1,10 @@ +/* + * 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 @@ -6,37 +13,41 @@ interface StyleBuilder { fun property(propertyName: String, value: StylePropertyValue) fun variable(variableName: String, value: StylePropertyValue) - fun property(propertyName: String, value: String) = property(propertyName, value.unsafeCast()) - fun property(propertyName: String, value: Number) = property(propertyName, value.unsafeCast()) - fun variable(variableName: String, value: Number) = variable(variableName, value.unsafeCast()) - fun variable(variableName: String, value: String) = variable(variableName, value.unsafeCast()) - - operator fun CSSStyleVariable.invoke(value: TValue) { - if (value is CustomStyleValue) { - variable(name, value.styleValue()) - } else { - variable(name, value.toString()) - } + 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 CSSStyleVariable.invoke(value: TValue) { + variable(name, value.toString()) } -} -fun variableValue(variableName: String, fallback: StylePropertyValue? = null) = - "var(--$variableName${fallback?.let { ", $it" } ?: ""})" + operator fun CSSStyleVariable.invoke(value: String) { + variable(name, value) + } -interface CSSVariableValue : StylePropertyValue { - companion object { - operator fun invoke(value: String) = - value.unsafeCast>() - operator fun invoke(value: Number) = - value.unsafeCast>() - operator fun invoke(value: TValue) = - value.unsafeCast>() - - operator fun invoke(value: StylePropertyValue) = - value.unsafeCast>() + operator fun CSSStyleVariable.invoke(value: Number) { + variable(name, value) } } +inline fun variableValue(variableName: String, fallback: StylePropertyValue? = null) = + "var(--$variableName${fallback?.let { ", $it" } ?: ""})" + +external interface CSSVariableValue : StylePropertyValue + +inline fun CSSVariableValue(value: String) = + StylePropertyValue(value).unsafeCast>() + +//fun CSSVariableValue(value: Number) = +// value.unsafeCast>() +// +//fun CSSVariableValue(value: TValue) = +// value.unsafeCast>() +// +//fun CSSVariableValue(value: StylePropertyValue) = +// value.unsafeCast>() + // after adding `variable` word `add` became ambiguous @Deprecated( "use property instead, will remove it soon", @@ -53,24 +64,17 @@ interface CSSVariable { val name: String } -interface CustomStyleValue { - fun styleValue(): StylePropertyValue -} - -data class CSSStyleVariable(override val name: String) : CSSVariable +class CSSStyleVariable(override val name: String) : CSSVariable -fun CSSStyleVariable.value(fallback: TValue? = null) = +fun CSSStyleVariable.value(fallback: TValue? = null) = CSSVariableValue( variableValue( name, - fallback?.let { - (fallback as? CustomStyleValue)?.styleValue() - ?: fallback.toString().unsafeCast() - } + fallback ) ) -fun CSSVariables.variable() = +fun CSSVariables.variable() = ReadOnlyProperty> { _, property -> CSSStyleVariable(property.name) } @@ -80,22 +84,17 @@ interface StyleHolder { 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(when (value) { - is CSSSizeValue<*> -> StylePropertyDeclaration(propertyName, value.asString()) - else -> StylePropertyDeclaration(propertyName, value) - }) + properties.add(StylePropertyDeclaration(propertyName, value)) } override fun variable(variableName: String, value: StylePropertyValue) { - variables.add(when (value) { - is CSSSizeValue<*> -> StylePropertyDeclaration(variableName, value.asString()) - else -> StylePropertyDeclaration(variableName, value) - }) + variables.add(StylePropertyDeclaration(variableName, value)) } // StylePropertyValue is js native object without equals diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/StylePropertyValue.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/StylePropertyValue.kt new file mode 100644 index 0000000000..cc9218f988 --- /dev/null +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/StylePropertyValue.kt @@ -0,0 +1,27 @@ +/* + * 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 + +external interface StylePropertyValue + +external interface StylePropertyNumber: StylePropertyValue +external interface StylePropertyString: StylePropertyValue + +inline fun StylePropertyValue(value: String): StylePropertyString = value.unsafeCast() +inline fun StylePropertyValue(value: Number): StylePropertyNumber = value.unsafeCast() + +fun StylePropertyValue.asString(): String? = if (jsTypeOf(this) == "string") this.unsafeCast() else null + +fun StylePropertyValue.asNumber(): Number? = if (jsTypeOf(this) == "number") this.unsafeCast() else null + +fun StylePropertyValue.asCSSStyleValue(): CSSStyleValue? = if (jsTypeOf(this) == "object") this.unsafeCast() else null + +external interface CSSStyleValue: StylePropertyValue { + override fun toString(): String +} + +inline fun CSSStyleValue(value: String): CSSStyleValue = StylePropertyValue(value).unsafeCast() diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/keywords/Keywords.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/keywords/Keywords.kt new file mode 100644 index 0000000000..93835c9daa --- /dev/null +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/keywords/Keywords.kt @@ -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. + */ + +package org.jetbrains.compose.web.css.keywords + +import org.jetbrains.compose.web.css.CSSKeywordValue + +external interface CSSAutoKeyword : CSSKeywordValue + +inline val auto: CSSAutoKeyword + get() = CSSKeywordValue("auto").unsafeCast() + diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/css/selectors/CSSSelectors.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/css/selectors/CSSSelectors.kt index 851e4fda33..4ad911013e 100644 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/css/selectors/CSSSelectors.kt +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/css/selectors/CSSSelectors.kt @@ -1,3 +1,5 @@ +@file:Suppress("EqualsOrHashCode", "unused", "MemberVisibilityCanBePrivate") + package org.jetbrains.compose.web.css.selectors import org.jetbrains.compose.web.css.LanguageCode diff --git a/web/core/src/jsMain/kotlin/androidx/compose/web/elements/Style.kt b/web/core/src/jsMain/kotlin/androidx/compose/web/elements/Style.kt index 0eef2d88bf..3bccae89e8 100644 --- a/web/core/src/jsMain/kotlin/androidx/compose/web/elements/Style.kt +++ b/web/core/src/jsMain/kotlin/androidx/compose/web/elements/Style.kt @@ -29,7 +29,7 @@ inline fun Style( * Use this function to mount the