diff --git a/CHANGELOG.md b/CHANGELOG.md index de37b16..dd647b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.0.39 + +* Add support of `Notifications` + ## 0.0.38 * Add support of `Toggle` diff --git a/gradle.properties b/gradle.properties index bbe19b7..c867ca4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,4 +9,4 @@ android.enableJetifier=true # Project data group=dev.inmo -version=0.0.38 +version=0.0.39 diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/elements/Dialog.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/elements/Dialog.kt index f6df0e2..0fa23ac 100644 --- a/src/jsMain/kotlin/dev/inmo/jsuikit/elements/Dialog.kt +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/elements/Dialog.kt @@ -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() } } } diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/elements/Notification.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/elements/Notification.kt new file mode 100644 index 0000000..6e95fcf --- /dev/null +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/elements/Notification.kt @@ -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) diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/modifiers/UIKit.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/modifiers/UIKit.kt index 96882df..f39df8b 100644 --- a/src/jsMain/kotlin/dev/inmo/jsuikit/modifiers/UIKit.kt +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/modifiers/UIKit.kt @@ -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() diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKit.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKit.kt new file mode 100644 index 0000000..3bf29fa --- /dev/null +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKit.kt @@ -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? +} diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitDialog.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitDialog.kt new file mode 100644 index 0000000..93aa44e --- /dev/null +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitDialog.kt @@ -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 { + val dialog: UIKitDialog + + fun then( + onConfirm: () -> Unit = definedExternally, + onRejected: () -> Unit = definedExternally, + ) +} + +external class UIKitDialogPromisePrompt : Promise { + val dialog: UIKitDialog + + fun then(onResult: (data: String?) -> Unit) +} + +external class UIKitDialogPromiseAlert : Promise { + val dialog: UIKitDialog + + fun then(onClose: () -> Unit) +} + +external interface UIKitDialog { + fun show() + fun hide() +} diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitNotificationParameter.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitNotificationParameter.kt new file mode 100644 index 0000000..15ab125 --- /dev/null +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitNotificationParameter.kt @@ -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") + + } + + } +} diff --git a/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitNotifications.kt b/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitNotifications.kt new file mode 100644 index 0000000..adff565 --- /dev/null +++ b/src/jsMain/kotlin/dev/inmo/jsuikit/types/UIKitNotifications.kt @@ -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))