Compare commits

...

22 Commits

Author SHA1 Message Date
21d2ccf208 Update CHANGELOG.md 2022-05-10 15:05:06 +06:00
fd6a122b40 Update libs.versions.toml 2022-05-10 15:04:54 +06:00
6b4e141cd2 update release version 2022-05-07 01:46:31 +06:00
fb5e0ade11 update compose dependency 2022-05-07 01:43:57 +06:00
353314dd26 add dev compose maven 2022-04-29 17:34:10 +06:00
57ffe32b9f Update of dependencies 2022-04-29 17:29:37 +06:00
c6bacffdb3 start 0.1.0 2022-04-29 17:28:52 +06:00
3e2aa22076 Merge pull request #54 from InsanusMokrassar/0.0.53
0.0.53
2022-04-27 16:29:24 +06:00
5842da03d0 new function ListWithTitle 2022-04-27 16:24:57 +06:00
6daa57fe8f improve support of List 2022-04-27 16:13:58 +06:00
8adbe8a1ca Add support of UIKit lists 2022-04-27 16:07:07 +06:00
468f167ac6 Improvements in UIKitPadding 2022-04-27 15:44:06 +06:00
c41e2b8495 start 0.0.53 2022-04-27 15:43:55 +06:00
7cdd12e81e Merge pull request #53 from InsanusMokrassar/0.0.52
0.0.52
2022-04-26 15:09:19 +06:00
f3ce0f6b6b Improve work with UIKitModifiers 2022-04-26 14:54:26 +06:00
d24edcbaf7 start 0.0.52 2022-04-26 14:54:19 +06:00
fdd98bab13 Merge pull request #52 from InsanusMokrassar/0.0.51
0.0.51
2022-04-15 13:21:20 +06:00
ed6582c98d now it is impossible to pass null in hide fun of dropdown 2022-04-15 13:20:30 +06:00
4b697938ac a little fix in hide of dropdown 2022-04-15 13:12:04 +06:00
ebb350c688 Improvements in Dropdowns and new attribute in NavItemElement 2022-04-15 13:06:14 +06:00
8c2ce7b75d start 0.0.51 2022-04-15 13:05:20 +06:00
2d62f9847a Merge pull request #51 from InsanusMokrassar/0.0.50
0.0.50
2022-04-04 00:57:44 +06:00
17 changed files with 311 additions and 61 deletions

View File

@@ -1,5 +1,24 @@
# Changelog # Changelog
## 0.1.0
* `Kotlin` = `1.6.21`
* `Compose`: `1.2.0-alpha01-dev682`
## 0.0.53
* Improvements in `UIKitPadding`
* Add support of UIKit lists
## 0.0.52
* Improve work with UIKitModifiers
## 0.0.51
* New interface `Dropdown` which will be used to create (or retrieve) dropdown for an element
* New attribute in `NavItemElement` for configuration of `A` element
## 0.0.50 ## 0.0.50
* Add opportunity to customize content in title of `Nav` after text * Add opportunity to customize content in title of `Nav` after text

View File

@@ -26,6 +26,7 @@ repositories {
mavenLocal() mavenLocal()
mavenCentral() mavenCentral()
google() google()
maven { url "https://maven.pkg.jetbrains.space/public/p/compose/dev" }
} }
kotlin { kotlin {

View File

@@ -9,4 +9,4 @@ android.enableJetifier=true
# Project data # Project data
group=dev.inmo group=dev.inmo
version=0.0.50 version=0.1.0

View File

@@ -1,9 +1,9 @@
[versions] [versions]
kt = "1.6.10" kt = "1.6.21"
jb-compose = "1.1.1" jb-compose = "1.2.0-alpha01-dev682"
jb-dokka = "1.6.10" jb-dokka = "1.6.21"
gh-release = "2.2.12" gh-release = "2.3.7"
[libraries] [libraries]

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -1,8 +1,7 @@
package dev.inmo.jsuikit package dev.inmo.jsuikit
import dev.inmo.jsuikit.modifiers.AttributeValue import dev.inmo.jsuikit.modifiers.AttributeValue
import dev.inmo.jsuikit.utils.AttributeBuilder import dev.inmo.jsuikit.utils.*
import dev.inmo.jsuikit.utils.buildAttribute
import org.jetbrains.compose.web.attributes.AttrsScope import org.jetbrains.compose.web.attributes.AttrsScope
@Deprecated("Will be removed soon") @Deprecated("Will be removed soon")
@@ -25,7 +24,7 @@ class UIKitAttributeValueBuilder {
fun AttrsScope<*>.buildAndAddAttribute( fun AttrsScope<*>.buildAndAddAttribute(
attributeName: String, attributeName: String,
skipNullValues: Boolean = true, skipNullValues: Boolean = true,
block: AttributeBuilder.() -> Unit block: ParametersBuilder.() -> Unit
) { ) {
buildAttribute(attributeName, skipNullValues, block).let { buildAttribute(attributeName, skipNullValues, block).let {
attr(it.first, it.second) attr(it.first, it.second)

View File

@@ -3,10 +3,26 @@ package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.buildAndAddAttribute import dev.inmo.jsuikit.buildAndAddAttribute
import dev.inmo.jsuikit.modifiers.* import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.types.DropdownOptions
import dev.inmo.jsuikit.utils.Milliseconds import dev.inmo.jsuikit.utils.Milliseconds
import org.jetbrains.compose.web.dom.* import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLDivElement import org.w3c.dom.HTMLDivElement
@Composable
fun Dropdown(
vararg modifiers: UIKitModifier,
dropdownOptions: DropdownOptions,
attributesCustomizer: AttrBuilderContext<HTMLDivElement> = {},
contentBuilder: ContentBuilder<HTMLDivElement>
) {
Div(
{
include(UIKitDropdown(dropdownOptions), *modifiers)
attributesCustomizer()
},
contentBuilder
)
}
@Composable @Composable
fun Dropdown( fun Dropdown(
vararg modifiers: UIKitModifier, vararg modifiers: UIKitModifier,
@@ -26,21 +42,24 @@ fun Dropdown(
) { ) {
Div( Div(
{ {
buildAndAddAttribute("uk-dropdown") { include(
"toggle" to toggle UIKitDropdown(
"pos" to pos DropdownOptions(
"mode" to mode toggle = toggle,
"delayShow" to delayShow pos = pos,
"delayHide" to delayHide mode = mode,
"boundary" to boundary delayShow = delayShow,
"boundaryAlign" to boundaryAlign delayHide = delayHide,
"flip" to flip boundary = boundary,
"offset" to offset boundaryAlign = boundaryAlign,
"animation" to animation flip = flip,
"duration" to duration offset = offset,
} animation = animation,
classes("uk-dropdown") duration = duration
include(*modifiers) )
),
*modifiers
)
attributesCustomizer() attributesCustomizer()
}, },
contentBuilder contentBuilder

View File

@@ -2,14 +2,32 @@ package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.snapshots.SnapshotStateList
import dev.inmo.jsuikit.modifiers.UIKitModifier import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.modifiers.include import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.dom.* import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLHeadingElement import org.w3c.dom.HTMLHeadingElement
import org.w3c.dom.HTMLUListElement import org.w3c.dom.HTMLUListElement
@Composable @Composable
fun <T> List( fun <T> List(
data: SnapshotStateList<T>,
ukAttrs: Attrs<HTMLUListElement> = Attrs.empty(),
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) {
Ul(
{
include(UIKitList)
ukAttrs.builder(this)
}
) {
data.forEach {
elementAllocator(it)
}
}
}
@Composable
fun <T> ListWithTitle(
title: String, title: String,
data: SnapshotStateList<T>, data: SnapshotStateList<T>,
vararg titleModifiers: UIKitModifier, vararg titleModifiers: UIKitModifier,
@@ -23,15 +41,27 @@ fun <T> List(
Text(title) Text(title)
} }
besidesTitleAndList ?.invoke() besidesTitleAndList ?.invoke()
Ul( List(data, Attrs(*ulModifiers) { ulCustomizer(this) }, elementAllocator)
{
classes("uk-list")
include(*ulModifiers)
ulCustomizer()
}
) {
data.forEach {
elementAllocator(it)
}
}
} }
@Deprecated("Renamed", ReplaceWith("ListWithTitle", "dev.inmo.jsuikit.elements.ListWithTitle"))
@Composable
fun <T> List(
title: String,
data: SnapshotStateList<T>,
vararg titleModifiers: UIKitModifier,
ulModifiers: Array<UIKitModifier> = emptyArray(),
besidesTitleAndList: (@Composable () -> Unit)? = null,
titleCustomizer: AttrBuilderContext<HTMLHeadingElement> = {},
ulCustomizer: AttrBuilderContext<HTMLUListElement> = {},
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) = ListWithTitle(
title,
data,
*titleModifiers,
ulModifiers = ulModifiers,
besidesTitleAndList = besidesTitleAndList,
titleCustomizer = titleCustomizer,
ulCustomizer = ulCustomizer,
elementAllocator = elementAllocator
)

View File

@@ -249,6 +249,7 @@ fun NavHeader(
fun NavItemElement( fun NavItemElement(
vararg modifiers: UIKitModifier, vararg modifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLLIElement> = {}, attributesCustomizer: AttrBuilderContext<HTMLLIElement> = {},
anchorAttributesCustomizer: AttrBuilderContext<HTMLAnchorElement> = {},
contentAllocator: ContentBuilder<HTMLAnchorElement> contentAllocator: ContentBuilder<HTMLAnchorElement>
) { ) {
Li( Li(
@@ -257,7 +258,7 @@ fun NavItemElement(
attributesCustomizer() attributesCustomizer()
} }
) { ) {
A("#") { A("#", attrs = anchorAttributesCustomizer) {
contentAllocator() contentAllocator()
} }
} }

View File

@@ -1,5 +1,9 @@
package dev.inmo.jsuikit.modifiers package dev.inmo.jsuikit.modifiers
import dev.inmo.jsuikit.types.DropdownOptions
import dev.inmo.jsuikit.utils.Milliseconds
import dev.inmo.jsuikit.utils.buildAttribute
sealed class UIKitDropdown(classname: String) : UIKitModifier { sealed class UIKitDropdown(classname: String) : UIKitModifier {
override val classes: Array<String> = arrayOf(classname) override val classes: Array<String> = arrayOf(classname)
@@ -64,4 +68,48 @@ sealed class UIKitDropdown(classname: String) : UIKitModifier {
} }
class Custom(
dropdownOptions: DropdownOptions
) : UIKitDropdown("uk-dropdown") {
override val otherAttrs: Map<String, String> = mapOf(
buildAttribute(
"uk-dropdown"
) {
dropdownOptions.includeParameters(this)
}
)
}
companion object {
operator fun invoke(
dropdownOptions: DropdownOptions
) = Custom(dropdownOptions)
operator fun invoke(
toggle: String? = null,
pos: Position? = null,
mode: Mode? = null,
delayShow: Milliseconds? = null,
delayHide: Milliseconds? = null,
boundary: String? = null,
boundaryAlign: Boolean? = null,
flip: Flip? = null,
offset: Int? = null,
animation: UIKitAnimation? = null,
duration: Milliseconds? = null,
) = Custom(
DropdownOptions(
toggle = toggle,
pos = pos,
mode = mode,
delayShow = delayShow,
delayHide = delayHide,
boundary = boundary,
boundaryAlign = boundaryAlign,
flip = flip,
offset = offset,
animation = animation,
duration = duration
)
)
}
} }

View File

@@ -0,0 +1,46 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitList(
vararg classes: String,
override val otherAttrs: Map<String, String> = emptyMap()
) : UIKitModifier {
@Suppress("UNCHECKED_CAST")
override val classes: Array<String> = classes as Array<String>
sealed class Style(vararg classes: String) : UIKitList(*classes) {
object Disc : Style("uk-list-disc")
object Circle : Style("uk-list-circle")
object Square : Style("uk-list-square")
object Decimal : Style("uk-list-decimal")
object Hyphen : Style("uk-list-hyphen")
}
sealed class Size(vararg classes: String) : UIKitList(*classes) {
object Large : Size("uk-list-large")
object Collapse : Size("uk-list-collapse")
}
sealed class Color(vararg classes: String) : UIKitList(*classes) {
object Muted : Color("uk-list-muted")
object Emphasis : Color("uk-list-emphasis")
object Primary : Color("uk-list-primary")
object Secondary : Color("uk-list-secondary")
companion object {
val Bullet = UIKitList.Bullet
}
}
object Bullet: UIKitList("uk-list-bullet")
object Divider: UIKitList("uk-list-divider")
object Striped: UIKitList("uk-list-striped")
companion object : UIKitList("uk-list")
}

View File

@@ -26,8 +26,8 @@ operator fun UIKitModifier.plus(other: UIKitModifier): UIKitModifier = UIKitCust
classes + other.classes, classes + other.classes,
otherAttrs + other.otherAttrs otherAttrs + other.otherAttrs
) )
fun <T: Element> UIKitModifier.builder() = Attrs<T>(this).builder fun <T: Element> UIKitModifier?.builder() = Attrs<T>(this).builder
fun <T: Element> Array<out UIKitModifier>.builder() = Attrs<T>(*this).builder fun <T: Element> Array<out UIKitModifier?>.builder() = Attrs<T>(*this).builder
inline fun <T: Element> attrsBuilder(vararg modifiers: UIKitModifier) = modifiers.builder<T>() inline fun <T: Element> attrsBuilder(vararg modifiers: UIKitModifier?) = modifiers.builder<T>()
@JsName("plusBuilder") @JsName("plusBuilder")
operator fun <T: Element> UIKitModifier.plus(other: UIKitModifier): AttrBuilderContext<T> = Attrs<T>(this@plus, other).builder operator fun <T: Element> UIKitModifier?.plus(other: UIKitModifier?): AttrBuilderContext<T> = Attrs<T>(this@plus, other).builder

View File

@@ -8,7 +8,10 @@ sealed class UIKitPadding(suffix: String?) : UIKitModifier {
object Small : Size("small") object Small : Size("small")
object Large : Size("large") object Large : Size("large")
companion object : Size(null) companion object : Size(null) {
val Default
get() = this
}
} }
@@ -25,5 +28,6 @@ sealed class UIKitPadding(suffix: String?) : UIKitModifier {
} }
companion object : Size(null)
} }

View File

@@ -0,0 +1,44 @@
package dev.inmo.jsuikit.types
import dev.inmo.jsuikit.modifiers.UIKitAnimation
import dev.inmo.jsuikit.modifiers.UIKitDropdown
import dev.inmo.jsuikit.utils.*
external interface Dropdown {
fun show()
fun hide(delay: Boolean = definedExternally)
fun hide(delay: Milliseconds)
}
data class DropdownOptions(
private val toggle: String? = null,
private val pos: UIKitDropdown.Position? = null,
private val mode: UIKitDropdown.Mode? = null,
private val delayShow: Milliseconds? = null,
private val delayHide: Milliseconds? = null,
private val boundary: String? = null,
private val boundaryAlign: Boolean? = null,
private val flip: UIKitDropdown.Flip? = null,
private val offset: Int? = null,
private val animation: UIKitAnimation? = null,
private val duration: Milliseconds? = null,
) {
fun includeParameters(parametersBuilder: ParametersBuilder) {
with(parametersBuilder) {
"toggle" to toggle
"pos" to pos
"mode" to mode
"delayShow" to delayShow
"delayHide" to delayHide
"boundary" to boundary
"boundaryAlign" to boundaryAlign
"flip" to flip
"offset" to offset
"animation" to animation
"duration" to duration
}
}
fun parameters() = buildParametersWithoutNulls {
includeParameters(this)
}
}

View File

@@ -13,4 +13,7 @@ external interface UIKit {
fun modal(element: Element): UIKitDialog fun modal(element: Element): UIKitDialog
fun modal(selector: String): UIKitDialog? fun modal(selector: String): UIKitDialog?
fun dropdown(element: Element, options: DropdownOptions = definedExternally): Dropdown
fun dropdown(selector: String, options: DropdownOptions = definedExternally): Dropdown?
} }

View File

@@ -2,26 +2,24 @@ package dev.inmo.jsuikit.utils
class AttributeBuilder ( class AttributeBuilder (
val attributeName: String, val attributeName: String,
val skipNullValues: Boolean = true, val parametersBuilder: ParametersBuilder
private val parametersPreset: MutableMap<String, String?> = mutableMapOf()
) { ) {
fun build(): Pair<String, String> = parametersBuilder.build().run {
fun add(k: String, v: Any? = null) { Pair(
if (v != null || !skipNullValues) { attributeName, toList().joinToString(";") {
parametersPreset[k] = v ?.toString()
}
}
infix fun String.to(value: Any?) = add(this, value)
operator fun String.unaryPlus() = add(this, null)
fun build(): Pair<String, String> = Pair(
attributeName, parametersPreset.toList().joinToString(";") {
"${it.first}${it.second ?.let { ": $it" } ?: ""}" "${it.first}${it.second ?.let { ": $it" } ?: ""}"
} }
) )
}
} }
inline fun buildAttribute(attributeName: String, skipNullValues: Boolean = true, block: AttributeBuilder.() -> Unit) = AttributeBuilder( inline fun buildAttribute(
attributeName: String,
skipNullValues: Boolean = true,
block: ParametersBuilder.() -> Unit
) = AttributeBuilder(
attributeName, attributeName,
skipNullValues ParametersBuilder(skipNullValues)
).apply(block).build() ).apply {
parametersBuilder.block()
}.build()

View File

@@ -0,0 +1,38 @@
package dev.inmo.jsuikit.utils
class ParametersBuilder(
val skipNullValues: Boolean = true,
private val parameters: MutableMap<String, String?> = mutableMapOf()
) {
fun add(k: String, v: Any? = null) {
if (v != null || !skipNullValues) {
parameters[k] = v ?.toString()
}
}
infix fun String.to(value: Any?) = add(this, value)
operator fun String.unaryPlus() = add(this, null)
operator fun Map<String, String?>.unaryPlus() = forEach {
}
fun build() = parameters.toMap()
fun buildNotNullable() = parameters.mapNotNull { (k, v) ->
if (v != null) {
Pair(k, v)
} else {
null
}
}.toMap()
}
fun buildParameters(
skipNullValues: Boolean = true,
block: ParametersBuilder.() -> Unit
) = ParametersBuilder(skipNullValues).apply(block).build()
fun buildParametersWithoutNulls(
skipNullValues: Boolean = true,
block: ParametersBuilder.() -> Unit
) = ParametersBuilder(skipNullValues).apply(block).buildNotNullable()