Repository: JetBrains/compose-multiplatform
File: html/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/StyleScope.kt (Kotlin)

Code before:
/**
 * 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, important: Boolean)
    fun property(propertyName: String, value: StylePropertyValue) = property(propertyName, value, false)
    fun variable(variableName: String, value: StylePropertyValue)

    fun property(propertyName: String, value: String, important: Boolean) = property(propertyName, StylePropertyValue(value), important)
    fun property(propertyName: String, value: String) = property(propertyName, value, false)
    fun property(propertyName: String, value: Number, important: Boolean) = property(propertyName, StylePropertyValue(value), important)
    fun property(propertyName: String, value: Number) = property(propertyName, value, false)
    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" } ?: ""})"

Review comment (suggestion):
The new methods in an interface should have a default implementaiton to remain source compatible:

The existing implementations (I mean potential implementations not in this project) implement the methods with 2 parameters.

I see two options for the default implementations of new 3arg methods:
-  just throw an error - "!important is not supported by this implementation"
- call the 2arg overloads dropping the `important` parameter

Usually, when an error is thrown then the problem will be noticed much earlier. So I'd choose the first option. WDYT?

Then we just make sure that our implementation of the interface overrides the new 3arg methods rather than uses the default (throwing an error).

Code after:
/**
 * 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)
    /**
     * Adds arbitrary CSS property to the inline style of the element. By default throws an error for backward compatibility
     * @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]
     * @param important - the flag which will be passed to property call in CSS
     *
     * 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", true)
     *      property("some-exotic-css-property-width", 5.px, false)
     *  }
     * })
     * ```
     */
    fun property(propertyName: String, value: StylePropertyValue, important: Boolean): Unit = error("!important is not supported by this implementation")
    fun variable(variableName: String, value: StylePropertyValue)

    fun property(propertyName: String, value: String) = property(propertyName, StylePropertyValue(value))
    fun property(propertyName: String, value: String, important: Boolean) = property(propertyName, StylePropertyValue(value), important)
    fun property(propertyName: String, value: Number) = property(propertyName, StylePropertyValue(value))
    fun property(propertyName: String, value: Number, important: Boolean) = property(propertyName, StylePropertyValue(value), important)