mirror of
https://github.com/InsanusMokrassar/JSUIKitKBindings.git
synced 2025-12-04 13:26:27 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 33fbd2c0be | |||
| b836fe744e | |||
| f77c21ac51 | |||
| c720973bfc | |||
| 0b11e2c1b9 | |||
| 556ab4e090 | |||
| a596516c79 | |||
| 8eeabc4b5d | |||
| 2a3f14593b | |||
| bfd6790014 | |||
| 27ad91be74 | |||
| 3c7f17523b | |||
| c81c1125a0 | |||
| 2e28334b41 | |||
| 7c33efa121 | |||
| 7b6a8c81b4 |
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,5 +1,21 @@
|
||||
# Changelog
|
||||
|
||||
## 0.0.41
|
||||
|
||||
* Add `DropArea`
|
||||
* Add `UIKitPlaceholder`
|
||||
* `UIKitForm#Custom` now have nullable param target
|
||||
* Add `UIKitUtility#Link`
|
||||
* Add `DescriptionList` and several support composable functions
|
||||
|
||||
## 0.0.40
|
||||
|
||||
* All `DefaultTable` functions now use `Iterable` as data type
|
||||
|
||||
## 0.0.39
|
||||
|
||||
* Add support of `Notifications`
|
||||
|
||||
## 0.0.38
|
||||
|
||||
* Add support of `Toggle`
|
||||
|
||||
@@ -9,4 +9,4 @@ android.enableJetifier=true
|
||||
# Project data
|
||||
|
||||
group=dev.inmo
|
||||
version=0.0.38
|
||||
version=0.0.41
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package dev.inmo.jsuikit.elements
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.inmo.jsuikit.modifiers.UIKitDescriptionList
|
||||
import dev.inmo.jsuikit.modifiers.include
|
||||
import dev.inmo.jsuikit.utils.*
|
||||
import org.jetbrains.compose.web.dom.ContentBuilder
|
||||
import org.jetbrains.compose.web.dom.ElementScope
|
||||
import org.w3c.dom.HTMLDListElement
|
||||
import org.w3c.dom.HTMLElement
|
||||
|
||||
@Composable
|
||||
fun DescriptionList(
|
||||
attrs: Attrs<HTMLDListElement>,
|
||||
contentBuilder: ContentBuilder<HTMLDListElement>
|
||||
) {
|
||||
DList(
|
||||
{
|
||||
include(UIKitDescriptionList)
|
||||
attrs.builder(this)
|
||||
},
|
||||
contentBuilder
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> DescriptionList(
|
||||
data: Iterable<T>,
|
||||
attrs: Attrs<HTMLDListElement>,
|
||||
beforeTermContent: (@Composable ElementScope<HTMLElement>.(Int, T) -> Unit)? = null,
|
||||
itemTermAttrs: ((Int, T) -> Attrs<HTMLElement>?)? = null,
|
||||
itemTermContent: (@Composable ElementScope<HTMLElement>.(Int, T) -> Unit)? = null,
|
||||
betweenTermAndDescriptionContent: (@Composable ElementScope<HTMLElement>.(Int, T) -> Unit)? = null,
|
||||
afterDescriptionContent: (@Composable ElementScope<HTMLElement>.(Int, T) -> Unit)? = null,
|
||||
itemDescriptionAttrs: ((Int, T) -> Attrs<HTMLElement>?)? = null,
|
||||
itemDescriptionContent: (@Composable ElementScope<HTMLElement>.(Int, T) -> Unit)? = null
|
||||
) {
|
||||
DescriptionList(attrs) {
|
||||
data.forEachIndexed { i, t ->
|
||||
beforeTermContent ?.invoke(this, i, t)
|
||||
if (itemTermAttrs != null || itemTermContent != null) {
|
||||
DTerm(
|
||||
itemTermAttrs ?.let { { it(i, t) } },
|
||||
itemTermContent ?.let { { it(i, t) } },
|
||||
)
|
||||
}
|
||||
betweenTermAndDescriptionContent ?.invoke(this, i, t)
|
||||
if (itemDescriptionAttrs != null || itemDescriptionContent != null) {
|
||||
DDescription(
|
||||
itemDescriptionAttrs ?.let { { it(i, t) } },
|
||||
itemDescriptionContent ?.let { { it(i, t) } },
|
||||
)
|
||||
}
|
||||
afterDescriptionContent ?.invoke(this, i, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ private class DialogDisposableEffectResult(
|
||||
) : DisposableEffectResult {
|
||||
override fun dispose() {
|
||||
onDispose?.invoke()
|
||||
js("UIkit").modal("#${element.id}") ?.hide()
|
||||
UIKit.modal("#${element.id}") ?.hide()
|
||||
onDisposed?.invoke()
|
||||
}
|
||||
}
|
||||
@@ -99,9 +99,7 @@ fun Dialog(
|
||||
}
|
||||
htmlElement.addEventListener("hidden", wrapper)
|
||||
|
||||
val dialog = UIKit.modal("#${htmlElement.id}")
|
||||
dialog.show()
|
||||
Unit
|
||||
UIKit.modal("#${htmlElement.id}") ?.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
src/jsMain/kotlin/dev/inmo/jsuikit/elements/DropArea.kt
Normal file
27
src/jsMain/kotlin/dev/inmo/jsuikit/elements/DropArea.kt
Normal file
@@ -0,0 +1,27 @@
|
||||
package dev.inmo.jsuikit.elements
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import dev.inmo.jsuikit.modifiers.*
|
||||
import dev.inmo.jsuikit.utils.Attrs
|
||||
import dev.inmo.jsuikit.utils.InputAttrs
|
||||
import org.jetbrains.compose.web.attributes.InputType
|
||||
import org.jetbrains.compose.web.dom.*
|
||||
import org.w3c.dom.HTMLDivElement
|
||||
import org.w3c.dom.HTMLInputElement
|
||||
|
||||
@Composable
|
||||
fun DropArea(
|
||||
attrs: Attrs<HTMLDivElement> = Attrs.empty(),
|
||||
inputAttrs: InputAttrs<String> = Attrs.empty(),
|
||||
contentBuilder: ContentBuilder<HTMLDivElement> = {}
|
||||
) = Div(
|
||||
{
|
||||
include(UIKitPlaceholder, UIKitForm.Custom())
|
||||
attrs.builder(this)
|
||||
}
|
||||
) {
|
||||
FileInput {
|
||||
inputAttrs.builder.invoke(this)
|
||||
}
|
||||
contentBuilder(this)
|
||||
}
|
||||
15
src/jsMain/kotlin/dev/inmo/jsuikit/elements/Notification.kt
Normal file
15
src/jsMain/kotlin/dev/inmo/jsuikit/elements/Notification.kt
Normal file
@@ -0,0 +1,15 @@
|
||||
package dev.inmo.jsuikit.elements
|
||||
|
||||
import dev.inmo.jsuikit.modifiers.UIKit
|
||||
import dev.inmo.jsuikit.types.UIKitNotificationParameter
|
||||
import dev.inmo.jsuikit.types.NotificationsGroup
|
||||
import dev.inmo.jsuikit.types.invoke
|
||||
import dev.inmo.jsuikit.utils.Milliseconds
|
||||
|
||||
fun Notification(
|
||||
message: String,
|
||||
status: UIKitNotificationParameter.Style? = null,
|
||||
timeout: Milliseconds? = null,
|
||||
group: NotificationsGroup? = null,
|
||||
position: UIKitNotificationParameter.Position? = null
|
||||
) = UIKit.notification.invoke(message, status, timeout, group, position)
|
||||
@@ -11,7 +11,7 @@ import org.w3c.dom.*
|
||||
@Composable
|
||||
fun <T> DefaultTable(
|
||||
headerBuilders: List<ContentBuilder<HTMLTableCellElement>>,
|
||||
dataList: SnapshotStateList<T>,
|
||||
dataList: Iterable<T>,
|
||||
vararg tableModifiers: UIKitModifier,
|
||||
attributesCustomizer: AttrBuilderContext<HTMLTableElement> = {},
|
||||
headerCustomizer: AttrBuilderContext<HTMLTableSectionElement> = {},
|
||||
@@ -68,7 +68,7 @@ fun <T> DefaultTable(
|
||||
@Composable
|
||||
fun <T> DefaultTable(
|
||||
heading: List<String>,
|
||||
dataList: SnapshotStateList<T>,
|
||||
dataList: Iterable<T>,
|
||||
vararg tableModifiers: UIKitModifier,
|
||||
attributesCustomizer: AttrBuilderContext<HTMLTableElement> = {},
|
||||
headerCustomizer: AttrBuilderContext<HTMLTableSectionElement> = {},
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
package dev.inmo.jsuikit.modifiers
|
||||
|
||||
inline val UIKit
|
||||
get() = js("UIkit")
|
||||
import dev.inmo.jsuikit.types.UIKit
|
||||
|
||||
inline val UIKit: UIKit
|
||||
get() = js("UIkit").unsafeCast<UIKit>()
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package dev.inmo.jsuikit.modifiers
|
||||
|
||||
sealed class UIKitDescriptionList(
|
||||
override val classes: Array<String>
|
||||
) : UIKitModifier {
|
||||
|
||||
object Divider : UIKitDescriptionList(arrayOf("uk-description-list-divider"))
|
||||
|
||||
companion object : UIKitDescriptionList(arrayOf("uk-description-list"))
|
||||
|
||||
}
|
||||
@@ -47,8 +47,9 @@ sealed class UIKitForm(
|
||||
object Icon : UIKitForm("uk-form-icon")
|
||||
|
||||
class Custom(
|
||||
target: String = "true"
|
||||
target: String? = null
|
||||
) : UIKitForm(
|
||||
"uk-form-custom",
|
||||
otherAttrs = mapOf(
|
||||
buildAttribute("uk-form-custom") {
|
||||
"target" to target
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package dev.inmo.jsuikit.modifiers
|
||||
|
||||
object UIKitPlaceholder : UIKitModifier {
|
||||
override val classes: Array<String> = arrayOf("uk-placeholder")
|
||||
}
|
||||
@@ -111,4 +111,5 @@ sealed class UIKitUtility(classname: String) : UIKitModifier {
|
||||
object Active : UIKitUtility("uk-active")
|
||||
|
||||
object Open : UIKitUtility("uk-open")
|
||||
object Link : UIKitUtility("uk-link")
|
||||
}
|
||||
|
||||
16
src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKit.kt
Normal file
16
src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKit.kt
Normal file
@@ -0,0 +1,16 @@
|
||||
package dev.inmo.jsuikit.types
|
||||
|
||||
import org.w3c.dom.Element
|
||||
import kotlin.js.Json
|
||||
|
||||
external interface UIKit {
|
||||
val notification: UIKitNotifications
|
||||
val modal: UIKitDialogs
|
||||
|
||||
|
||||
fun notification(message: String, parameters: Json)
|
||||
fun notification(element: Element): UIKitNotification?
|
||||
|
||||
fun modal(element: Element): UIKitDialog
|
||||
fun modal(selector: String): UIKitDialog?
|
||||
}
|
||||
38
src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitDialog.kt
Normal file
38
src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitDialog.kt
Normal file
@@ -0,0 +1,38 @@
|
||||
package dev.inmo.jsuikit.types
|
||||
|
||||
import org.w3c.dom.Element
|
||||
import kotlin.js.Promise
|
||||
|
||||
external interface UIKitDialogs {
|
||||
fun alert(text: String): UIKitDialogPromiseAlert
|
||||
fun confirm(text: String): UIKitDialogPromiseConfirm
|
||||
fun prompt(title: String): UIKitDialogPromisePrompt
|
||||
fun prompt(title: String, preset: String): UIKitDialogPromisePrompt
|
||||
fun dialog(element: Element): UIKitDialog
|
||||
}
|
||||
|
||||
external class UIKitDialogPromiseConfirm : Promise<Unit> {
|
||||
val dialog: UIKitDialog
|
||||
|
||||
fun then(
|
||||
onConfirm: () -> Unit = definedExternally,
|
||||
onRejected: () -> Unit = definedExternally,
|
||||
)
|
||||
}
|
||||
|
||||
external class UIKitDialogPromisePrompt : Promise<Unit> {
|
||||
val dialog: UIKitDialog
|
||||
|
||||
fun then(onResult: (data: String?) -> Unit)
|
||||
}
|
||||
|
||||
external class UIKitDialogPromiseAlert : Promise<Unit> {
|
||||
val dialog: UIKitDialog
|
||||
|
||||
fun then(onClose: () -> Unit)
|
||||
}
|
||||
|
||||
external interface UIKitDialog {
|
||||
fun show()
|
||||
fun hide()
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package dev.inmo.jsuikit.types
|
||||
|
||||
sealed class UIKitNotificationParameter {
|
||||
abstract val parameterName: String
|
||||
abstract val parameterValue: String
|
||||
|
||||
sealed class Style(override val parameterValue: String) : UIKitNotificationParameter() {
|
||||
override val parameterName: String
|
||||
get() = "status"
|
||||
|
||||
object Primary : Style("primary")
|
||||
object Success : Style("success")
|
||||
object Warning : Style("warning")
|
||||
object Danger : Style("danger")
|
||||
|
||||
}
|
||||
|
||||
sealed class Position(override val parameterValue: String) : UIKitNotificationParameter() {
|
||||
override val parameterName: String
|
||||
get() = "pos"
|
||||
|
||||
sealed class Top(parameterValue: String) : Position("top-$parameterValue") {
|
||||
|
||||
object Left : Top("left")
|
||||
object Center : Top("center")
|
||||
object Right : Top("right")
|
||||
|
||||
}
|
||||
|
||||
sealed class Bottom(parameterValue: String) : Position("bottom-$parameterValue") {
|
||||
|
||||
object Left : Bottom("left")
|
||||
object Center : Bottom("center")
|
||||
object Right : Bottom("right")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package dev.inmo.jsuikit.types
|
||||
|
||||
import dev.inmo.jsuikit.modifiers.UIKit
|
||||
import dev.inmo.jsuikit.utils.Milliseconds
|
||||
import org.w3c.dom.Element
|
||||
import kotlin.js.Json
|
||||
import kotlin.js.json
|
||||
|
||||
typealias NotificationsGroup = String
|
||||
|
||||
external interface UIKitNotifications {
|
||||
|
||||
fun closeAll(group: NotificationsGroup)
|
||||
}
|
||||
|
||||
external interface UIKitNotification {
|
||||
fun close(immediate: Boolean)
|
||||
}
|
||||
|
||||
data class UIKitNotificationsParameters(
|
||||
val status: UIKitNotificationParameter.Style? = null,
|
||||
val timeout: Milliseconds? = null,
|
||||
val group: NotificationsGroup? = null,
|
||||
val position: UIKitNotificationParameter.Position? = null
|
||||
) {
|
||||
fun parametersJson() = json(
|
||||
*listOfNotNull(
|
||||
status ?.let { it.parameterName to it.parameterValue },
|
||||
timeout ?.let { "timeout" to timeout.toString() },
|
||||
group ?.let { "group" to it },
|
||||
position ?.let { it.parameterName to it.parameterValue },
|
||||
).toTypedArray()
|
||||
)
|
||||
}
|
||||
|
||||
operator fun UIKitNotifications.invoke(
|
||||
message: String,
|
||||
parameters: UIKitNotificationsParameters
|
||||
) = UIKit.notification(message, parameters.parametersJson())
|
||||
|
||||
operator fun UIKitNotifications.invoke(
|
||||
message: String,
|
||||
status: UIKitNotificationParameter.Style? = null,
|
||||
timeout: Milliseconds? = null,
|
||||
group: NotificationsGroup? = null,
|
||||
position: UIKitNotificationParameter.Position? = null
|
||||
) = invoke(message, UIKitNotificationsParameters(status, timeout, group, position))
|
||||
@@ -3,19 +3,22 @@ package dev.inmo.jsuikit.utils
|
||||
import dev.inmo.jsuikit.modifiers.UIKitModifier
|
||||
import dev.inmo.jsuikit.modifiers.include
|
||||
import org.jetbrains.compose.web.attributes.AttrsBuilder
|
||||
import org.jetbrains.compose.web.attributes.InputType
|
||||
import org.jetbrains.compose.web.attributes.builders.InputAttrsBuilder
|
||||
import org.jetbrains.compose.web.dom.AttrBuilderContext
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.HTMLInputElement
|
||||
|
||||
class AttributesCollection<T : Element> (
|
||||
private vararg val modifiers: UIKitModifier,
|
||||
private val attrs: AttrBuilderContext<T> = {}
|
||||
class AttributesCollection<T : Element, Builder : AttrsBuilder<T>> (
|
||||
private vararg val modifiers: UIKitModifier?,
|
||||
private val attrs: Builder.() -> Unit = {}
|
||||
) {
|
||||
val builder: AttrBuilderContext<T> = {
|
||||
val builder: Builder.() -> Unit = {
|
||||
include(*modifiers)
|
||||
attrs()
|
||||
}
|
||||
|
||||
operator fun plus(other: AttributesCollection<T>) = AttributesCollection<T>(
|
||||
operator fun plus(other: AttributesCollection<T, Builder>) = AttributesCollection<T, Builder>(
|
||||
*(modifiers + other.modifiers).distinct().toTypedArray()
|
||||
) {
|
||||
this@AttributesCollection.attrs.invoke(this)
|
||||
@@ -26,8 +29,9 @@ class AttributesCollection<T : Element> (
|
||||
val Empty = Attrs<Element>()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : Element> empty() = Empty as Attrs<T>
|
||||
fun <T : Element, Builder : AttrsBuilder<T>> empty() = Empty as AttributesCollection<T, Builder>
|
||||
}
|
||||
}
|
||||
|
||||
typealias Attrs<T> = AttributesCollection<T>
|
||||
typealias Attrs<T> = AttributesCollection<T, AttrsBuilder<T>>
|
||||
typealias InputAttrs<T> = AttributesCollection<HTMLInputElement, InputAttrsBuilder<T>>
|
||||
|
||||
55
src/jsMain/kotlin/dev/inmo/jsuikit/utils/Dlist.kt
Normal file
55
src/jsMain/kotlin/dev/inmo/jsuikit/utils/Dlist.kt
Normal file
@@ -0,0 +1,55 @@
|
||||
package dev.inmo.jsuikit.utils
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import kotlinx.browser.document
|
||||
import org.jetbrains.compose.web.dom.*
|
||||
import org.w3c.dom.*
|
||||
|
||||
private object DListElementBuilder : ElementBuilder<HTMLDListElement> {
|
||||
private val el: Element by lazy { document.createElement("dl") }
|
||||
override fun create(): HTMLDListElement = el.cloneNode() as HTMLDListElement
|
||||
}
|
||||
|
||||
private object DTermElementBuilder : ElementBuilder<HTMLElement> {
|
||||
private val el: Element by lazy { document.createElement("dt") }
|
||||
override fun create(): HTMLElement = el.cloneNode() as HTMLElement
|
||||
}
|
||||
|
||||
private object DDescriptionElementBuilder : ElementBuilder<HTMLElement> {
|
||||
private val el: Element by lazy { document.createElement("dd") }
|
||||
override fun create(): HTMLElement = el.cloneNode() as HTMLElement
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DList(
|
||||
attrs: AttrBuilderContext<HTMLDListElement>? = null,
|
||||
content: ContentBuilder<HTMLDListElement>? = null
|
||||
) {
|
||||
TagElement(
|
||||
DListElementBuilder,
|
||||
attrs,
|
||||
content
|
||||
)
|
||||
}
|
||||
@Composable
|
||||
fun DTerm(
|
||||
attrs: AttrBuilderContext<HTMLElement>? = null,
|
||||
content: ContentBuilder<HTMLElement>? = null
|
||||
) {
|
||||
TagElement(
|
||||
DTermElementBuilder,
|
||||
attrs,
|
||||
content
|
||||
)
|
||||
}
|
||||
@Composable
|
||||
fun DDescription(
|
||||
attrs: AttrBuilderContext<HTMLElement>? = null,
|
||||
content: ContentBuilder<HTMLElement>? = null
|
||||
) {
|
||||
TagElement(
|
||||
DDescriptionElementBuilder,
|
||||
attrs,
|
||||
content
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user