diff options
Diffstat (limited to 'src/main/kotlin/pl/treksoft')
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/ApplicationBase.kt | 2 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/HMR.kt | 2 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/Main.kt | 3 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/Showcase.kt | 14 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/basic/Label.kt | 2 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/core/Container.kt | 2 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt | 18 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/core/Root.kt | 2 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/core/Widget.kt | 25 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt | 31 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/html/Button.kt | 11 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/html/Image.kt | 7 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/html/List.kt | 9 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/html/Tag.kt | 15 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt | 21 |
15 files changed, 103 insertions, 61 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/ApplicationBase.kt b/src/main/kotlin/pl/treksoft/kvision/ApplicationBase.kt index a7b3d465..e9e99fc7 100644 --- a/src/main/kotlin/pl/treksoft/kvision/ApplicationBase.kt +++ b/src/main/kotlin/pl/treksoft/kvision/ApplicationBase.kt @@ -3,4 +3,4 @@ package pl.treksoft.kvision abstract class ApplicationBase { abstract fun start(state: Map<String, Any>) abstract fun dispose(): Map<String, Any> -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/HMR.kt b/src/main/kotlin/pl/treksoft/kvision/HMR.kt index 1251c187..e657567a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/HMR.kt +++ b/src/main/kotlin/pl/treksoft/kvision/HMR.kt @@ -16,4 +16,4 @@ external interface Hot { fun dispose(callback: (data: dynamic) -> Unit) } -external fun require(name: String): dynamic
\ No newline at end of file +external fun require(name: String): dynamic diff --git a/src/main/kotlin/pl/treksoft/kvision/Main.kt b/src/main/kotlin/pl/treksoft/kvision/Main.kt index 918cd51f..385d23e8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/Main.kt +++ b/src/main/kotlin/pl/treksoft/kvision/Main.kt @@ -1,7 +1,6 @@ package pl.treksoft.kvision -import kotlin.browser.* -import kotlin.dom.* +import kotlin.browser.document fun main(args: Array<String>) { var application: ApplicationBase? = null diff --git a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt index 67d7bbd1..b2e6d764 100644 --- a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt +++ b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt @@ -33,7 +33,8 @@ class Showcase : ApplicationBase() { val dd = DropDown("Dropdown", listOf("abc" to "#!/x", "def" to "#!/y"), "flag") root.add(dd) - val dd2 = DropDown("Dropdown2", listOf("abc" to "#!/abc", "def" to "#!/def", "xyz" to DISABLED.POS, "Header" to HEADER.POS, "Separtatorek" to SEPARATOR.POS + val dd2 = DropDown("Dropdown2", listOf("abc" to "#!/abc", "def" to "#!/def", "xyz" to DISABLED.POS, + "Header" to HEADER.POS, "Separtatorek" to SEPARATOR.POS ), "flag", dropup = true) root.add(dd2) @@ -43,7 +44,8 @@ class Showcase : ApplicationBase() { val del = Tag(TAG.DEL, "To jest deleted") root.add(del) - val list = ListTag(LIST.DL_HORIZ, listOf("abc", "de<b>fdasdasdasddasd</b>tdasdas", "Dasdsada", "dasdasdads"), true) + val list = ListTag(LIST.DL_HORIZ, listOf("abc", "de<b>fdasdasdasddasd</b>tdasdas", "Dasdsada", + "dasdasdads"), true) root.add(list) val list2 = ListTag(LIST.OL, null) @@ -52,15 +54,15 @@ class Showcase : ApplicationBase() { list2.add(Image(Img("kotlin.png"))) root.add(list2) - val img = Image(Img("kotlin.png"), "Image", true, IMAGE_SHAPE.ROUNDED) + val img = Image(Img("kotlin.png"), "Image", true, IMAGESHAPE.ROUNDED) root.add(img) - val button = Button("To jest przycisk FA", "fa-flag", BUTTON_STYLE.DANGER) + val button = Button("To jest przycisk FA", "fa-flag", BUTTONSTYLE.DANGER) button.setEventListener<Button> { click = { _ -> println(self.text) } } root.add(button) - val button2 = Button("To jest przycisk", "flag", BUTTON_STYLE.DANGER) + val button2 = Button("To jest przycisk", "flag", BUTTONSTYLE.DANGER) button2.setEventListener { click = { e -> println("2" + e) @@ -114,4 +116,4 @@ class Showcase : ApplicationBase() { KVManager.shutdown() return mapOf<String, Any>() } -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/basic/Label.kt b/src/main/kotlin/pl/treksoft/kvision/basic/Label.kt index cf0587db..a8d8bc16 100644 --- a/src/main/kotlin/pl/treksoft/kvision/basic/Label.kt +++ b/src/main/kotlin/pl/treksoft/kvision/basic/Label.kt @@ -3,4 +3,4 @@ package pl.treksoft.kvision.basic import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag -open class Label(text: String, rich: Boolean = false) : Tag(TAG.SPAN, text, rich)
\ No newline at end of file +open class Label(text: String, rich: Boolean = false) : Tag(TAG.SPAN, text, rich) diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Container.kt b/src/main/kotlin/pl/treksoft/kvision/core/Container.kt index e21fd669..e8d277dc 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Container.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Container.kt @@ -35,4 +35,4 @@ open class Container(classes: Set<String> = setOf()) : Widget(classes) { children.removeAt(index).clearParent() refresh() } -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt b/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt index 97f0fd62..ab95a162 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt @@ -1,16 +1,24 @@ package pl.treksoft.kvision.core -import com.github.snabbdom.* +import com.github.snabbdom.Snabbdom +import com.github.snabbdom.VNode +import com.github.snabbdom.attributesModule +import com.github.snabbdom.classModule +import com.github.snabbdom.datasetModule +import com.github.snabbdom.eventListenersModule +import com.github.snabbdom.propsModule +import com.github.snabbdom.styleModule import pl.treksoft.kvision.require import pl.treksoft.kvision.routing.routing import kotlin.browser.document import kotlin.dom.clear object KVManager { - private val bootstrap_webpack = require("bootstrap-webpack") - private val font_awesome_webpack = require("font-awesome-webpack") + private val bootstrapWebpack = require("bootstrap-webpack") + private val fontAwesomeWebpack = require("font-awesome-webpack") - private val sdPatch = Snabbdom.init(arrayOf(classModule, attributesModule, propsModule, styleModule, eventListenersModule, datasetModule)) + private val sdPatch = Snabbdom.init(arrayOf(classModule, attributesModule, propsModule, styleModule, + eventListenersModule, datasetModule)) private val sdVirtualize = require("snabbdom-virtualize/strings").default internal fun patch(id: String, vnode: VNode): VNode { @@ -31,4 +39,4 @@ object KVManager { fun shutdown() { routing.destroy() } -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Root.kt b/src/main/kotlin/pl/treksoft/kvision/core/Root.kt index b5911c36..bea4db5e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Root.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Root.kt @@ -24,4 +24,4 @@ class Root(id: String, private val fluid: Boolean = false) : Container() { vnode = KVManager.patch(vnode, render()) } -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index 34a3aa81..a1405135 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -1,11 +1,18 @@ package pl.treksoft.kvision.core -import com.github.snabbdom.On import com.github.snabbdom.VNode import com.github.snabbdom.VNodeData import com.github.snabbdom.h -import pl.treksoft.kvision.snabbdom.* - +import pl.treksoft.kvision.snabbdom.on +import pl.treksoft.kvision.snabbdom.SnOn +import pl.treksoft.kvision.snabbdom.StringBoolPair +import pl.treksoft.kvision.snabbdom.StringPair +import pl.treksoft.kvision.snabbdom.snAttrs +import pl.treksoft.kvision.snabbdom.snClasses +import pl.treksoft.kvision.snabbdom.snOpt +import pl.treksoft.kvision.snabbdom.snStyle + +@Suppress("TooManyFunctions") open class Widget(classes: Set<String> = setOf()) : KVObject { val classes = classes.toMutableSet() @@ -49,9 +56,9 @@ open class Widget(classes: Set<String> = setOf()) : KVObject { protected open fun getSnOpt(): VNodeData { return snOpt { - attrs = snAttrs(* getSnAttrs().toTypedArray()) - style = snStyle(* getSnStyle().toTypedArray()) - `class` = snClasses(* getSnClass().toTypedArray()) + attrs = snAttrs(getSnAttrs()) + style = snStyle(getSnStyle()) + `class` = snClasses(getSnClass()) on = getSnOn() } } @@ -79,8 +86,8 @@ open class Widget(classes: Set<String> = setOf()) : KVObject { return snattrs } - protected open fun getSnOn(): On { - val handlers = On(this) + protected open fun getSnOn(): com.github.snabbdom.On { + val handlers = on(this) listeners.forEach { on -> (handlers::apply)(on) } return handlers } @@ -126,4 +133,4 @@ open class Widget(classes: Set<String> = setOf()) : KVObject { protected open fun refresh() { this.parent?.refresh() } -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt index c0a87297..18946b27 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt +++ b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt @@ -2,7 +2,14 @@ package pl.treksoft.kvision.dropdown import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.ResString -import pl.treksoft.kvision.html.* +import pl.treksoft.kvision.html.BUTTONSIZE +import pl.treksoft.kvision.html.BUTTONSTYLE +import pl.treksoft.kvision.html.Button +import pl.treksoft.kvision.html.LIST +import pl.treksoft.kvision.html.Link +import pl.treksoft.kvision.html.ListTag +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.snabbdom.StringPair enum class DD(val POS: String) { @@ -11,10 +18,13 @@ enum class DD(val POS: String) { SEPARATOR("DD#SEPARATOR") } -open class DropDown(text: String, elements: List<StringPair>, icon: String? = null, style: BUTTON_STYLE = BUTTON_STYLE.DEFAULT, size: BUTTON_SIZE? = null, - block: Boolean = false, disabled: Boolean = false, image: ResString? = null, dropup: Boolean = false, classes: Set<String> = setOf()) : Container(classes) { +open class DropDown(text: String, elements: List<StringPair>, icon: String? = null, + style: BUTTONSTYLE = BUTTONSTYLE.DEFAULT, size: BUTTONSIZE? = null, + block: Boolean = false, disabled: Boolean = false, image: ResString? = null, + dropup: Boolean = false, classes: Set<String> = setOf()) : Container(classes) { val idc = "kv_dropdown_" + counter - val button: DropDownButton = DropDownButton(idc, text, icon, style, size, block, disabled, image, setOf("dropdown")) + val button: DropDownButton = DropDownButton(idc, text, icon, style, size, block, + disabled, image, setOf("dropdown")) val list: DropDownListTag = DropDownListTag(idc, setOf("dropdown-menu")) init { @@ -46,8 +56,9 @@ open class DropDown(text: String, elements: List<StringPair>, icon: String? = nu } } -open class DropDownButton(id: String, text: String, icon: String? = null, style: BUTTON_STYLE = BUTTON_STYLE.DEFAULT, size: BUTTON_SIZE? = null, - block: Boolean = false, disabled: Boolean = false, image: ResString? = null, classes: Set<String> = setOf()) : +open class DropDownButton(id: String, text: String, icon: String? = null, style: BUTTONSTYLE = BUTTONSTYLE.DEFAULT, + size: BUTTONSIZE? = null, block: Boolean = false, disabled: Boolean = false, + image: ResString? = null, classes: Set<String> = setOf()) : Button(text, icon, style, size, block, disabled, image, classes) { init { @@ -55,12 +66,14 @@ open class DropDownButton(id: String, text: String, icon: String? = null, style: } override fun getSnAttrs(): List<StringPair> { - return super.getSnAttrs() + listOf("data-toggle" to "dropdown", "aria-haspopup" to "true", "aria-expanded" to "false") + return super.getSnAttrs() + listOf("data-toggle" to "dropdown", "aria-haspopup" to "true", + "aria-expanded" to "false") } } -open class DropDownListTag(val ariaId: String, classes: Set<String> = setOf()) : ListTag(LIST.UL, null, false, classes) { +open class DropDownListTag(val ariaId: String, classes: Set<String> = setOf()) : ListTag(LIST.UL, null, + false, classes) { override fun getSnAttrs(): List<StringPair> { return super.getSnAttrs() + listOf("aria-labelledby" to ariaId) } -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt index 81df4eaf..0fe2f559 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt @@ -7,7 +7,7 @@ import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.snabbdom.StringBoolPair import pl.treksoft.kvision.snabbdom.StringPair -enum class BUTTON_STYLE(val className: String) { +enum class BUTTONSTYLE(val className: String) { DEFAULT("btn-default"), PRIMARY("btn-primary"), SUCCESS("btn-success"), @@ -17,14 +17,15 @@ enum class BUTTON_STYLE(val className: String) { LINK("btn-link") } -enum class BUTTON_SIZE(val className: String) { +enum class BUTTONSIZE(val className: String) { LARGE("btn-lg"), SMALL("btn-sm"), XSMALL("btn-xs") } -open class Button(text: String, icon: String? = null, style: BUTTON_STYLE = BUTTON_STYLE.DEFAULT, size: BUTTON_SIZE? = null, - block: Boolean = false, disabled: Boolean = false, image: ResString? = null, classes: Set<String> = setOf()) : Widget(classes) { +open class Button(text: String, icon: String? = null, style: BUTTONSTYLE = BUTTONSTYLE.DEFAULT, + size: BUTTONSIZE? = null, block: Boolean = false, disabled: Boolean = false, + image: ResString? = null, classes: Set<String> = setOf()) : Widget(classes) { var text = text set(value) { field = value @@ -96,4 +97,4 @@ open class Button(text: String, icon: String? = null, style: BUTTON_STYLE = BUTT return super.getSnAttrs() + ("type" to "button") } -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt index 3e9fe5d6..a03d673a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt @@ -6,13 +6,14 @@ import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.snabbdom.StringBoolPair import pl.treksoft.kvision.snabbdom.StringPair -enum class IMAGE_SHAPE(val className: String) { +enum class IMAGESHAPE(val className: String) { ROUNDED("img-rounded"), CIRCLE("img-circle"), THUMBNAIL("img-thumbnail") } -open class Image(src: ResString, alt: String? = null, responsive: Boolean = false, shape: IMAGE_SHAPE? = null, centered: Boolean = false, classes: Set<String> = setOf()) : Widget(classes) { +open class Image(src: ResString, alt: String? = null, responsive: Boolean = false, shape: IMAGESHAPE? = null, + centered: Boolean = false, classes: Set<String> = setOf()) : Widget(classes) { var src = src set(value) { field = value @@ -63,4 +64,4 @@ open class Image(src: ResString, alt: String? = null, responsive: Boolean = fals } return cl } -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/List.kt b/src/main/kotlin/pl/treksoft/kvision/html/List.kt index e525d9a5..24978f8d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/List.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/List.kt @@ -15,7 +15,8 @@ enum class LIST(val tagName: String) { DL_HORIZ("dl") } -open class ListTag(type: LIST, elements: List<String>? = null, rich: Boolean = false, classes: Set<String> = setOf()) : Container(classes) { +open class ListTag(type: LIST, elements: List<String>? = null, rich: Boolean = false, + classes: Set<String> = setOf()) : Container(classes) { var type = type set(value) { field = value @@ -35,7 +36,9 @@ open class ListTag(type: LIST, elements: List<String>? = null, rich: Boolean = f override fun render(): VNode { val childrenElements = when (type) { LIST.UL, LIST.OL, LIST.UNSTYLED, LIST.INLINE -> elements?.map { el -> element("li", el, rich) } - LIST.DL, LIST.DL_HORIZ -> elements?.mapIndexed { index, el -> element(if (index % 2 == 0) "dt" else "dd", el, rich) } + LIST.DL, LIST.DL_HORIZ -> elements?.mapIndexed { index, el -> + element(if (index % 2 == 0) "dt" else "dd", el, rich) + } }?.toTypedArray() if (childrenElements != null) { return kvh(type.tagName, childrenElements + childrenVNodes()) @@ -84,4 +87,4 @@ open class ListTag(type: LIST, elements: List<String>? = null, rich: Boolean = f } return cl } -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt index 4a3f708f..37a7bf98 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt @@ -5,6 +5,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.KVManager import pl.treksoft.kvision.snabbdom.StringBoolPair +@Suppress("EnumNaming") enum class TAG(val tagName: String) { H1("h1"), H2("h2"), @@ -45,7 +46,8 @@ enum class ALIGN(val className: String) { NOWRAP("text-nowrap") } -open class Tag(type: TAG, text: String? = null, rich: Boolean = false, align: ALIGN = ALIGN.NONE, classes: Set<String> = setOf()) : Container(classes) { +open class Tag(type: TAG, text: String? = null, rich: Boolean = false, align: ALIGN = ALIGN.NONE, + classes: Set<String> = setOf()) : Container(classes) { var type = type set(value) { field = value @@ -68,15 +70,16 @@ open class Tag(type: TAG, text: String? = null, rich: Boolean = false, align: AL } override fun render(): VNode { - if (text != null) { + val ret = if (text != null) { if (rich) { - return kvh(type.tagName, arrayOf(KVManager.virtualize("<span>$text</span>")) + childrenVNodes()) + kvh(type.tagName, arrayOf(KVManager.virtualize("<span>$text</span>")) + childrenVNodes()) } else { - return kvh(type.tagName, arrayOf(text) + childrenVNodes()) + kvh(type.tagName, arrayOf(text) + childrenVNodes()) } } else { - return kvh(type.tagName, childrenVNodes()) + kvh(type.tagName, childrenVNodes()) } + return ret } override fun getSnClass(): List<StringBoolPair> { @@ -86,4 +89,4 @@ open class Tag(type: TAG, text: String? = null, rich: Boolean = false, align: AL } return cl } -}
\ No newline at end of file +} diff --git a/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt b/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt index 789417e6..3bf68003 100644 --- a/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt +++ b/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt @@ -1,6 +1,11 @@ package pl.treksoft.kvision.snabbdom -import com.github.snabbdom.* +import com.github.snabbdom.Attrs +import com.github.snabbdom.Classes +import com.github.snabbdom.On +import com.github.snabbdom.Props +import com.github.snabbdom.VNodeData +import com.github.snabbdom.VNodeStyle import pl.treksoft.kvision.core.Widget external class Object @@ -10,16 +15,16 @@ fun obj(init: dynamic.() -> Unit): dynamic { } @Suppress("UnsafeCastFromDynamic") -private fun VNodeData(): VNodeData = js("({})") +private fun vNodeData(): VNodeData = js("({})") interface SnOn<T> : On { var self: T } -fun snOpt(block: VNodeData.() -> Unit) = (VNodeData()::apply)(block) +fun snOpt(block: VNodeData.() -> Unit) = (vNodeData()::apply)(block) @Suppress("UnsafeCastFromDynamic") -internal fun On(widget: Widget): SnOn<Widget> { +internal fun on(widget: Widget): SnOn<Widget> { val obj = js("({})") obj["self"] = widget return obj @@ -29,28 +34,28 @@ typealias StringPair = Pair<String, String> typealias StringBoolPair = Pair<String, Boolean> @Suppress("UnsafeCastFromDynamic") -fun snStyle(vararg pairs: StringPair): VNodeStyle { +fun snStyle(pairs: List<StringPair>): VNodeStyle { return obj { pairs.forEach { (key, value) -> this[key] = value } } } @Suppress("UnsafeCastFromDynamic") -fun snProps(vararg pairs: StringPair): Props { +fun snProps(pairs: List<StringPair>): Props { return obj { pairs.forEach { (key, value) -> this[key] = value } } } @Suppress("UnsafeCastFromDynamic") -fun snClasses(vararg pairs: StringBoolPair): Classes { +fun snClasses(pairs: List<StringBoolPair>): Classes { return obj { pairs.forEach { (key, value) -> this[key] = value } } } @Suppress("UnsafeCastFromDynamic") -fun snAttrs(vararg pairs: StringPair): Attrs { +fun snAttrs(pairs: List<StringPair>): Attrs { return obj { pairs.forEach { (key, value) -> this[key] = value } } |