diff --git a/CHANGELOG.md b/CHANGELOG.md index 52d32ad..e64e1b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.2.1 +* `Tab` elements become supported + ## 0.2.0 **ALL DEPRECATIONS HAVE BEEN REMOVED** diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/elements/Tabs.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/elements/Tabs.kt new file mode 100644 index 0000000..0dedc10 --- /dev/null +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/elements/Tabs.kt @@ -0,0 +1,46 @@ +package dev.inmo.jsuikit.elements + +import androidx.compose.runtime.Composable +import dev.inmo.jsuikit.modifiers.UIKitTab +import dev.inmo.jsuikit.modifiers.include +import dev.inmo.jsuikit.utils.optionallyDraw +import org.jetbrains.compose.web.attributes.AttrsScope +import org.jetbrains.compose.web.dom.* +import org.w3c.dom.HTMLLIElement +import org.w3c.dom.HTMLUListElement + +@Composable +fun Tabs( + data: Iterable, + tabsItemBuilder: @Composable ElementScope.(i: Int, data: T) -> Unit, + tabsItemAttrs: AttrsScope.(i: Int, data: T) -> Unit = { _, _ -> }, + tabsContainerAttrs: AttrsScope.() -> Unit = {}, + contentContainerAttrs: (AttrsScope.() -> Unit)? = null, + contentItemAttrs: (AttrsScope.(i: Int, data: T) -> Unit)? = null, + contentItemBuilder: (@Composable ElementScope.(i: Int, data: T) -> Unit)? = null +) { + Ul({ + include(UIKitTab); + tabsContainerAttrs() + }) { + data.forEachIndexed { i, data -> + Li({ tabsItemAttrs(i, data) }) { + tabsItemBuilder(i, data) + } + } + } + + optionallyDraw(contentItemAttrs != null, contentItemBuilder != null, contentContainerAttrs != null) { + Ul({ + contentContainerAttrs ?.invoke(this) + }) { + optionallyDraw(contentItemAttrs != null, contentItemBuilder != null) { + data.forEachIndexed { i, data -> + Li({ contentItemAttrs ?.invoke(this, i, data) }) { + contentItemBuilder ?.invoke(this, i, data) + } + } + } + } + } +} diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/modifiers/UIKitTab.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/modifiers/UIKitTab.kt new file mode 100644 index 0000000..281f147 --- /dev/null +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/modifiers/UIKitTab.kt @@ -0,0 +1,51 @@ +package dev.inmo.jsuikit.modifiers + +import dev.inmo.jsuikit.utils.buildAttribute +import org.jetbrains.compose.web.css.selectors.CSSSelector +import kotlin.time.Duration + +sealed class UIKitTab( + override val classes: Array = emptyArray(), + override val otherAttrs: Map = emptyMap() +) : UIKitModifier { + sealed class Position( + classes: Array = emptyArray(), + otherAttrs: Map = emptyMap() + ) : UIKitTab(classes, otherAttrs) { + object Bottom : Position(arrayOf("uk-tab-bottom")) + object Left : Position(arrayOf("uk-tab-left")) + object Right : Position(arrayOf("uk-tab-right")) + } + + class Custom( + connect: CSSSelector? = null, + toggle: CSSSelector? = null, + active: Int? = null, + animationsIn: Array? = null, + animationsOut: Array? = null, + animationDuration: Duration? = null, + swiping: Boolean? = null, + media: String? = null + ) : UIKitTab( + arrayOf("uk-tab"), + mapOf( + buildAttribute("uk-tab") { + "connect" to connect + "toggle" to toggle + "active" to active + "animation" to ( + (animationsIn ?.let { + it.joinToString(" ") { it.name } + } ?: "") + (animationsOut ?.let { + it.joinToString(" ", ",") { it.name } + } ?: "") + ).takeIf { it.isNotBlank() } + "duration" to animationDuration + "swiping" to swiping + "media" to media + } + ) + ) + + companion object : UIKitTab(arrayOf("uk-tab"), mapOf("uk-tab" to "")) +} diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/utils/AttributesCollection.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/utils/AttributesCollection.kt index 13d3ca8..db5988c 100644 --- a/src/jsMain/kotlin/dev/inmo/jsuikit/utils/AttributesCollection.kt +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/utils/AttributesCollection.kt @@ -3,7 +3,9 @@ package dev.inmo.jsuikit.utils import dev.inmo.jsuikit.modifiers.UIKitModifier import dev.inmo.jsuikit.modifiers.include import org.jetbrains.compose.web.attributes.AttrsScope +import org.jetbrains.compose.web.attributes.HtmlAttrMarker import org.jetbrains.compose.web.attributes.builders.InputAttrsScope +import org.jetbrains.compose.web.dom.AttrBuilderContext import org.w3c.dom.Element import org.w3c.dom.HTMLInputElement diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/utils/OptionallyDraw.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/utils/OptionallyDraw.kt index dcad048..3bb5b19 100644 --- a/src/jsMain/kotlin/dev/inmo/jsuikit/utils/OptionallyDraw.kt +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/utils/OptionallyDraw.kt @@ -4,13 +4,19 @@ import androidx.compose.runtime.Composable import org.jetbrains.compose.web.dom.ContentBuilder import org.w3c.dom.Element +@Composable +inline fun optionallyDraw ( + vararg bools: Boolean, + whatToDraw: @Composable () -> Unit +) { + if (bools.any { it }) { + whatToDraw() + } +} + @Composable inline fun optionallyDraw ( attrs: Attrs? = null, noinline contentBuilder: ContentBuilder? = null, whatToDraw: @Composable () -> Unit -) { - if (attrs != null || contentBuilder != null) { - whatToDraw() - } -} +) = optionallyDraw(attrs != null || contentBuilder != null, whatToDraw = whatToDraw)