Compare commits

...

21 Commits

Author SHA1 Message Date
3c7f17523b refactor invoke functions 2022-03-01 00:49:19 +06:00
c81c1125a0 add UIKitDialog 2022-03-01 00:14:17 +06:00
2e28334b41 add support of notifications 2022-02-28 23:55:09 +06:00
7c33efa121 start 0.0.39 2022-02-28 23:54:59 +06:00
7b6a8c81b4 Merge pull request #39 from InsanusMokrassar/0.0.38
0.0.38
2022-02-25 00:36:19 +06:00
031d07d97a AttributesCollection#plus 2022-02-25 00:22:17 +06:00
a2eda2726b add UIKitToggle 2022-02-25 00:12:20 +06:00
eb15ce9281 start 0.0.38 2022-02-25 00:12:02 +06:00
3b3319c8aa Merge pull request #38 from InsanusMokrassar/0.0.37
0.0.37
2022-02-24 14:44:23 +06:00
0b40c3acf0 remove auto margin from dialog 2022-02-24 14:42:45 +06:00
ebbfac6763 fix in Accordion and UIKitAccordion.Companion 2022-02-23 23:10:19 +06:00
6f913c0a83 Accordion 2022-02-23 20:25:27 +06:00
528f6652e0 start 0.0.37 2022-02-23 20:25:13 +06:00
e3ba921018 Merge pull request #37 from InsanusMokrassar/0.0.36
0.0.36
2022-02-18 15:18:00 +06:00
44c35c6778 support of UIKitForm 2022-02-17 19:31:31 +06:00
7b06e0ecb1 add UIKitCustom 2022-02-17 17:46:15 +06:00
366971bcf5 add afterHeaderBuilder and beforeFooterBuilder in Dialog 2022-02-17 17:28:42 +06:00
d4d0adf020 vertical and horizontal in margins 2022-02-17 15:16:30 +06:00
fc2fb24fce reorder comment arguments 2022-02-17 14:57:09 +06:00
687c3ab065 start 0.0.36 2022-02-17 14:56:47 +06:00
70f1abd527 Merge pull request #36 from InsanusMokrassar/0.0.35
0.0.35
2022-02-17 14:09:11 +06:00
20 changed files with 511 additions and 23 deletions

View File

@@ -1,5 +1,27 @@
# Changelog
## 0.0.39
* Add support of `Notifications`
## 0.0.38
* Add support of `Toggle`
* Attributes collection now can be concatenated
## 0.0.37
* `Dialog` now do not add auto margin by default
* Support of `Accordion` element
## 0.0.36
* Reorder arguments in `DefaultComment` fun
* Add `Vertical` and `Horizontal` members in margins
* Add `afterHeaderBuilder` and `beforeFooterBuilder` properties in `Dialog` fun
* Add `UIKitCustom` to be able for simple creating of custom modifiers
* Add support of `UIKitForm`
## 0.0.35
* Add `UIKitModal`

View File

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

View File

@@ -0,0 +1,89 @@
package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.UIKitAccordion
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.attributes.AttrsBuilder
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.*
@Composable
fun <T> Accordion(
data: Iterable<T>,
attrs: Attrs<HTMLUListElement> = Attrs.empty(),
itemAttrsBuilder: AttrsBuilder<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
itemContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit
) {
Ul(
{
include(UIKitAccordion)
attrs.builder(this)
}
) {
data.forEachIndexed { i, t ->
Li({ itemAttrsBuilder(i, t) }) {
itemContentBuilder(i, t)
}
}
}
}
@Composable
fun <T> DefaultAccordion(
data: Iterable<T>,
attrs: Attrs<HTMLUListElement> = Attrs.empty(),
itemAttrsBuilder: AttrsBuilder<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
titleAttrsBuilder: AttrsBuilder<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
titleContentBuilder: @Composable ElementScope<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
beforeTitleContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
afterTitleContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
afterContentContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
contentAttrsBuilder: AttrsBuilder<HTMLDivElement>.(Int, T) -> Unit = { _, _ -> },
contentContentBuilder: @Composable ElementScope<HTMLDivElement>.(Int, T) -> Unit
) = Accordion(
data,
attrs,
itemAttrsBuilder
) { i, t ->
beforeTitleContentBuilder(i, t)
A(
attrs = {
include(UIKitAccordion.Title)
titleAttrsBuilder(i, t)
}
) {
titleContentBuilder(i, t)
}
afterTitleContentBuilder(i, t)
Div(
{
include(UIKitAccordion.Content)
contentAttrsBuilder(i, t)
}
) {
contentContentBuilder(i, t)
}
afterContentContentBuilder(i, t)
}
@Composable
fun <T> DefaultAccordion(
data: Iterable<T>,
titleResolver: (Int, T) -> String,
attrs: Attrs<HTMLUListElement> = Attrs.empty(),
itemAttrsBuilder: AttrsBuilder<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
titleAttrsBuilder: AttrsBuilder<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
contentAttrsBuilder: AttrsBuilder<HTMLDivElement>.(Int, T) -> Unit = { _, _ -> },
contentContentBuilder: @Composable ElementScope<HTMLDivElement>.(Int, T) -> Unit
) = DefaultAccordion(
data,
attrs,
itemAttrsBuilder,
titleAttrsBuilder,
{ i, t ->
org.jetbrains.compose.web.dom.Text(titleResolver(i, t))
},
contentAttrsBuilder = contentAttrsBuilder,
contentContentBuilder = contentContentBuilder
)

View File

@@ -45,16 +45,16 @@ fun Comment(
@Composable
fun DefaultComment(
rootAttrs: Attrs<HTMLElement> = Attrs.empty(),
headerGridAttrs: Attrs<HTMLDivElement>? = null,
headerAttrs: Attrs<HTMLElement>? = null,
additionalHeaderContent: ContentBuilder<HTMLElement>? = null,
avatarUrl: String? = null,
avatarAttrs: Attrs<HTMLImageElement>? = null,
titleAttrs: Attrs<HTMLHeadingElement>? = null,
titleContent: ContentBuilder<HTMLHeadingElement>? = null,
metaAttrs: Attrs<HTMLUListElement>? = null,
metaContent: ContentBuilder<HTMLUListElement>? = null,
rootAttrs: Attrs<HTMLElement> = Attrs.empty(),
headerAttrs: Attrs<HTMLElement>? = null,
additionalHeaderContent: ContentBuilder<HTMLElement>? = null,
bodyAttrs: Attrs<HTMLDivElement>? = null,
bodyContent: ContentBuilder<HTMLDivElement>? = null,
) {

View File

@@ -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()
}
}
@@ -31,6 +31,8 @@ fun Dialog(
dialogAttrsBuilder: AttrBuilderContext<HTMLDivElement>? = null,
headerAttrsBuilder: AttrBuilderContext<HTMLDivElement>? = null,
headerBuilder: ContentBuilder<HTMLDivElement>? = null,
afterHeaderBuilder: ContentBuilder<HTMLDivElement>? = null,
beforeFooterBuilder: ContentBuilder<HTMLDivElement>? = null,
footerAttrsBuilder: AttrBuilderContext<HTMLDivElement>? = null,
footerBuilder: ContentBuilder<HTMLDivElement>? = null,
bodyAttrsBuilder: AttrBuilderContext<HTMLDivElement>? = null,
@@ -42,7 +44,7 @@ fun Dialog(
include(UIKitModal)
}
id("dialog${Random.nextUInt()}")
include(*modifiers, UIKitFlex.Alignment.Vertical.Top)
include(*modifiers)
attributesCustomizer()
}
) {
@@ -62,6 +64,7 @@ fun Dialog(
it()
}
}
afterHeaderBuilder ?.let { it() }
Div(
{
include(UIKitModal.Body)
@@ -70,6 +73,7 @@ fun Dialog(
) {
bodyBuilder()
}
beforeFooterBuilder ?.let { it() }
footerBuilder ?.let {
Div(
{
@@ -95,9 +99,7 @@ fun Dialog(
}
htmlElement.addEventListener("hidden", wrapper)
val dialog = UIKit.modal("#${htmlElement.id}")
dialog.show()
Unit
UIKit.modal("#${htmlElement.id}") ?.show()
}
}
}

View File

@@ -250,4 +250,12 @@ sealed class Icon(val name: String) {
attributesCustomizer: AttrBuilderContext<out HTMLElement> = {},
onClick: ((Event) -> Unit)? = null
) = invoke(*modifiers, type = UIKitIconType.Link, ratio = ratio, onClick = onClick, attributesCustomizer = attributesCustomizer)
@Composable
fun drawAsFormInputPart(
vararg modifiers: UIKitModifier,
ratio: Float? = null,
attributesCustomizer: AttrBuilderContext<out HTMLElement> = {},
onClick: ((Event) -> Unit)? = null
) = invoke(*modifiers, UIKitForm.Icon, ratio = ratio, onClick = onClick, attributesCustomizer = attributesCustomizer)
}

View 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)

View File

@@ -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>()

View File

@@ -0,0 +1,51 @@
package dev.inmo.jsuikit.modifiers
import dev.inmo.jsuikit.utils.*
import org.w3c.dom.PageTransitionEvent
sealed class UIKitAccordion(
vararg classnames: String,
override val otherAttrs: Map<String, String> = emptyMap()
) : UIKitModifier {
@Suppress("UNCHECKED_CAST")
override val classes: Array<String> = classnames as Array<String>
object Title : UIKitAccordion("uk-accordion-title")
object Content : UIKitAccordion("uk-accordion-content")
class Custom internal constructor(
otherAttrs: Map<String, String> = emptyMap()
) : UIKitAccordion (otherAttrs = otherAttrs)
companion object : UIKitAccordion("uk-accordion", otherAttrs = mapOf("uk-accordion" to "")) {
val Open = UIKitUtility.Open
operator fun invoke(
activeItemIndex: Int? = null,
animation: Boolean? = null,
collapsible: Boolean? = null,
contentSelector: String? = null,
animationDuration: Milliseconds? = null,
multiple: Boolean? = null,
targetsSelector: String? = null,
toggleSelector: String? = null,
transition: PageTransitionEvent? = null,
offsetTopPixels: Int? = null,
) = Custom(
mapOf(
buildAttribute("uk-accordion") {
"active" to activeItemIndex
"animation" to animation
"collapsible" to collapsible
"content" to contentSelector
"duration" to animationDuration
"multiple" to multiple
"targets" to targetsSelector
"toggle" to toggleSelector
"transition" to transition
"offset" to offsetTopPixels
}
)
)
}
}

View File

@@ -62,4 +62,7 @@ sealed class UIKitAnimation (name: String) : UIKitModifier, AttributeValue(name)
object KenBurns : UIKitAnimation("kenburns")
override fun toString(): String {
return classes.joinToString(" ")
}
}

View File

@@ -0,0 +1,6 @@
package dev.inmo.jsuikit.modifiers
class UIKitCustom(
override val classes: Array<String> = emptyArray(),
override val otherAttrs: Map<String, String> = emptyMap()
) : UIKitModifier

View File

@@ -0,0 +1,58 @@
package dev.inmo.jsuikit.modifiers
import dev.inmo.jsuikit.utils.buildAttribute
sealed class UIKitForm(
vararg classnames: String,
override val otherAttrs: Map<String, String> = emptyMap()
) : UIKitModifier {
@Suppress("UNCHECKED_CAST")
override val classes: Array<String> = classnames as Array<String>
object Fieldset : UIKitForm("uk-fieldset")
object Legend : UIKitForm("uk-legend")
object Input : UIKitForm("uk-input")
object Select : UIKitForm("uk-select")
object TextArea : UIKitForm("uk-textarea")
object Radio : UIKitForm("uk-radio", otherAttrs = mapOf("type" to "radio"))
object Checkbox : UIKitForm("uk-checkbox", otherAttrs = mapOf("type" to "checkbox"))
object Range : UIKitForm("uk-range", otherAttrs = mapOf("type" to "range"))
sealed class State(vararg classnames: String) : UIKitForm(*classnames) {
object Danger : State("uk-form-danger")
object Success : State("uk-form-success")
}
sealed class Size(vararg classnames: String) : UIKitForm(*classnames) {
object Large : Size("uk-form-large")
object Default : Size() // :)
object Small : Size("uk-form-small")
}
sealed class Width(vararg classnames: String) : UIKitForm(*classnames) {
object Large : Width("uk-form-width-large")
object Medium : Width("uk-form-width-medium")
object Small : Width("uk-form-width-small")
object XSmall : Width("uk-form-width-xsmall")
}
object Blank : UIKitForm("uk-form-blank")
sealed class Layout(vararg classnames: String) : UIKitForm(*classnames) {
object Stacked : Layout("uk-form-stacked")
object Horizontal : Layout("uk-form-horizontal")
object Label : Layout("uk-form-label")
object Controls : Layout("uk-form-controls")
}
object Icon : UIKitForm("uk-form-icon")
class Custom(
target: String = "true"
) : UIKitForm(
otherAttrs = mapOf(
buildAttribute("uk-form-custom") {
"target" to target
}
)
)
}

View File

@@ -1,68 +1,87 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitMargin(val classname: String) : UIKitModifier {
override val classes: Array<String> = arrayOf(classname)
sealed class UIKitMargin(vararg classnames: String) : UIKitModifier {
@Suppress("UNCHECKED_CAST")
override val classes: Array<String> = classnames as Array<String>
object Top : Small("uk-margin-top")
object Bottom : Small("uk-margin-bottom")
object Left : Small("uk-margin-left")
object Right : Small("uk-margin-right")
object Top : UIKitMargin("uk-margin-top")
object Bottom : UIKitMargin("uk-margin-bottom")
object Left : UIKitMargin("uk-margin-left")
object Right : UIKitMargin("uk-margin-right")
object Vertical : UIKitMargin() { override val classes: Array<String> = Top.classes + Bottom.classes }
object Horizontal : UIKitMargin() { override val classes: Array<String> = Left.classes + Right.classes }
companion object : Small("uk-margin")
sealed class Small(classname: String) : UIKitMargin(classname) {
sealed class Small(vararg classnames: String) : UIKitMargin(*classnames) {
object Top : Small("uk-margin-small-top")
object Bottom : Small("uk-margin-small-bottom")
object Left : Small("uk-margin-small-left")
object Right : Small("uk-margin-small-right")
object Vertical : Small() {
override val classes: Array<String> = Top.classes + Bottom.classes
}
object Horizontal : Small() {
override val classes: Array<String> = Left.classes + Right.classes
}
companion object : Small("uk-margin-small")
}
sealed class Medium(classname: String) : UIKitMargin(classname) {
sealed class Medium(vararg classnames: String) : UIKitMargin(*classnames) {
object Top : Medium("uk-margin-medium-top")
object Bottom : Medium("uk-margin-medium-bottom")
object Left : Medium("uk-margin-medium-left")
object Right : Medium("uk-margin-medium-right")
object Vertical : Medium() { override val classes: Array<String> = Top.classes + Bottom.classes }
object Horizontal : Medium() { override val classes: Array<String> = Left.classes + Right.classes }
companion object : Medium("uk-margin-medium")
}
sealed class Large(classname: String) : UIKitMargin(classname) {
sealed class Large(vararg classnames: String) : UIKitMargin(*classnames) {
object Top : Large("uk-margin-large-top")
object Bottom : Large("uk-margin-large-bottom")
object Left : Large("uk-margin-large-left")
object Right : Large("uk-margin-large-right")
object Vertical : Large() { override val classes: Array<String> = Top.classes + Bottom.classes }
object Horizontal : Large() { override val classes: Array<String> = Left.classes + Right.classes }
companion object : Large("uk-margin-large")
}
sealed class XLarge(classname: String) : UIKitMargin(classname) {
sealed class XLarge(vararg classnames: String) : UIKitMargin(*classnames) {
object Top : XLarge("uk-margin-xlarge-top")
object Bottom : XLarge("uk-margin-xlarge-bottom")
object Left : XLarge("uk-margin-xlarge-left")
object Right : XLarge("uk-margin-xlarge-right")
object Vertical : XLarge() { override val classes: Array<String> = Top.classes + Bottom.classes }
object Horizontal : XLarge() { override val classes: Array<String> = Left.classes + Right.classes }
companion object : XLarge("uk-margin-xlarge")
}
sealed class Auto(classname: String) : UIKitMargin(classname) {
sealed class Auto(vararg classnames: String) : UIKitMargin(*classnames) {
object Top : Auto("uk-margin-auto-top")
object Bottom : Auto("uk-margin-auto-bottom")
object Left : Auto("uk-margin-auto-left")
object Right : Auto("uk-margin-auto-right")
object Vertical : Auto("uk-margin-auto-vertical")
object Horizontal : Auto() { override val classes: Array<String> = Left.classes + Right.classes }
companion object : Auto("uk-margin-auto")
}
sealed class Remove(classname: String) : UIKitMargin(classname) {
sealed class Remove(vararg classnames: String) : UIKitMargin(*classnames) {
object Top : Remove("uk-margin-remove-top")
object Bottom : Remove("uk-margin-remove-bottom")
object Left : Remove("uk-margin-remove-left")
object Right : Remove("uk-margin-remove-right")
object Vertical : Remove("uk-margin-remove-vertical")
object Horizontal : Remove() { override val classes: Array<String> = Left.classes + Right.classes }
object Adjacent : Remove("uk-margin-remove-adjacent")
object FirstChild : Remove("uk-margin-remove-first-child")
object LastChild : Remove("uk-margin-remove-last-child")

View File

@@ -0,0 +1,64 @@
package dev.inmo.jsuikit.modifiers
import dev.inmo.jsuikit.utils.Milliseconds
import dev.inmo.jsuikit.utils.buildAttribute
sealed class UIKitToggle(
vararg classnames: String,
override val otherAttrs: Map<String, String>
) : UIKitModifier {
@Suppress("UNCHECKED_CAST")
override val classes: Array<String> = classnames as Array<String>
sealed class Mode {
abstract val mode: String
object Click : Mode() {
override val mode: String
get() = "click"
}
object Hover : Mode() {
override val mode: String
get() = "hover"
}
object ClickAndHover : Mode() {
override val mode: String
get() = "${Click.mode}, ${Hover.mode}"
}
object Media : Mode() {
override val mode: String
get() = "media"
}
override fun toString(): String = mode
}
class Custom internal constructor(otherAttrs: Map<String, String>) : UIKitToggle(otherAttrs = otherAttrs)
companion object {
operator fun invoke(
target: String? = null,
mode: Mode? = null,
classesToApplyOnToggle: String? = null,
media: String? = null,
animation: UIKitAnimation? = null,
duration: Milliseconds? = null,
queued: Boolean? = null
) = Custom(
mapOf(
buildAttribute("uk-toggle") {
"target" to target
"mode" to mode
"cls" to classesToApplyOnToggle
"media" to media
"animation" to animation
"duration" to duration
"queued" to queued
}
)
)
}
}

View File

@@ -109,4 +109,6 @@ sealed class UIKitUtility(classname: String) : UIKitModifier {
object Disabled : UIKitUtility("uk-disabled")
object Drag : UIKitUtility("uk-drag")
object Active : UIKitUtility("uk-active")
object Open : UIKitUtility("uk-open")
}

View 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?
}

View 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()
}

View File

@@ -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")
}
}
}

View File

@@ -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))

View File

@@ -15,6 +15,13 @@ class AttributesCollection<T : Element> (
attrs()
}
operator fun plus(other: AttributesCollection<T>) = AttributesCollection<T>(
*(modifiers + other.modifiers).distinct().toTypedArray()
) {
this@AttributesCollection.attrs.invoke(this)
other.attrs.invoke(this)
}
companion object {
val Empty = Attrs<Element>()