diff options
-rw-r--r-- | build.gradle.kts | 3 | ||||
-rw-r--r-- | kvision-modules/kvision-toast/build.gradle.kts | 48 | ||||
-rw-r--r-- | kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/KVManagerToast.kt | 38 | ||||
-rw-r--r-- | kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/toast/Toast.kt | 178 | ||||
-rw-r--r-- | kvision-modules/kvision-toast/webpack.config.d/bootstrap.js | 3 | ||||
-rw-r--r-- | kvision-modules/kvision-toast/webpack.config.d/css.js | 2 | ||||
-rw-r--r-- | kvision-modules/kvision-toast/webpack.config.d/file.js | 9 | ||||
-rw-r--r-- | settings.gradle.kts | 1 | ||||
-rw-r--r-- | src/main/resources/css/style.css | 25 |
9 files changed, 306 insertions, 1 deletions
diff --git a/build.gradle.kts b/build.gradle.kts index 4f83c4b7..4a8e6607 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -130,7 +130,8 @@ tasks { "kvision-tabulator", "kvision-tabulator-remote", "kvision-server-javalin", - "kvision-server-vertx" + "kvision-server-vertx", + "kvision-toast" ) multiplatform { val js by creating { diff --git a/kvision-modules/kvision-toast/build.gradle.kts b/kvision-modules/kvision-toast/build.gradle.kts new file mode 100644 index 00000000..36ea4949 --- /dev/null +++ b/kvision-modules/kvision-toast/build.gradle.kts @@ -0,0 +1,48 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("toastr", "2.1.4")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") { + filter { it.replace("\"main\": \"kotlin/kvision-kvision", "\"main\": \"kvision-kvision") } + } + } +} diff --git a/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/KVManagerToast.kt b/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/KVManagerToast.kt new file mode 100644 index 00000000..5c6e1441 --- /dev/null +++ b/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/KVManagerToast.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package pl.treksoft.kvision + +internal val kVManagerToastInit = KVManagerToast.init() + +/** + * Internal singleton object which initializes and configures KVision Toast module. + */ +internal object KVManagerToast { + + init { + require("toastr/build/toastr.min.css") + } + + internal val toastr = require("toastr/build/toastr.min.js") + + internal fun init() {} +} diff --git a/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/toast/Toast.kt b/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/toast/Toast.kt new file mode 100644 index 00000000..99201dc5 --- /dev/null +++ b/kvision-modules/kvision-toast/src/main/kotlin/pl/treksoft/kvision/toast/Toast.kt @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package pl.treksoft.kvision.toast + +import pl.treksoft.kvision.KVManagerToast +import pl.treksoft.kvision.utils.obj + +/** + * Toast message types. + */ +internal enum class ToastType(internal val type: String) { + INFO("info"), + SUCCESS("success"), + WARNING("warning"), + ERROR("error") +} + +/** + * Toast positions. + */ +enum class ToastPosition(internal val position: String) { + TOPRIGHT("toast-top-right"), + BOTTOMRIGHT("toast-bottom-right"), + BOTTOMLEFT("toast-bottom-left"), + TOPLEFT("toast-top-left"), + TOPFULLWIDTH("toast-top-full-width"), + BOTTOMFULLWIDTH("toast-bottom-full-width"), + TOPCENTER("toast-top-center"), + BOTTOMCENTER("toast-bottom-center") +} + +/** + * Toast easings. + */ +enum class ToastEasing(internal val easing: String) { + SWING("swing"), + LINEAR("linear") +} + +/** + * Toast animation methods. + */ +enum class ToastMethod(internal val method: String) { + FADEIN("fadeIn"), + FADEOUT("fadeOut"), + SLIDEUP("slideUp"), + SLIDEDOWN("slideDown"), + SHOW("show"), + HIDE("hide") +} + +/** + * Toast options. + */ +data class ToastOptions( + val positionClass: ToastPosition? = null, + val escapeHtml: Boolean? = null, + val closeButton: Boolean? = null, + val closeHtml: String? = null, + val closeDuration: Int? = null, + val newestOnTop: Boolean? = null, + val showEasing: ToastEasing? = null, + val hideEasing: ToastEasing? = null, + val closeEasing: ToastEasing? = null, + val showMethod: ToastMethod? = null, + val hideMethod: ToastMethod? = null, + val closeMethod: ToastMethod? = null, + val preventDuplicates: Boolean? = null, + val timeOut: Int? = null, + val extendedTimeOut: Int? = null, + val progressBar: Boolean? = null, + val rtl: Boolean? = null, + val onShown: (() -> Unit)? = null, + val onHidden: (() -> Unit)? = null, + val onClick: (() -> Unit)? = null, + val onCloseClick: (() -> Unit)? = null +) + +internal fun ToastOptions.toJs(): dynamic { + return obj { + if (positionClass != null) this.positionClass = positionClass.position + if (escapeHtml != null) this.escapeHtml = escapeHtml + if (closeButton != null) this.closeButton = closeButton + if (closeHtml != null) this.closeHtml = closeHtml + if (closeDuration != null) this.closeDuration = closeDuration + if (newestOnTop != null) this.newestOnTop = newestOnTop + if (showEasing != null) this.showEasing = showEasing.easing + if (hideEasing != null) this.hideEasing = hideEasing.easing + if (closeEasing != null) this.closeEasing = closeEasing.easing + if (showMethod != null) this.showMethod = showMethod.method + if (hideMethod != null) this.hideMethod = hideMethod.method + if (closeMethod != null) this.closeMethod = closeMethod.method + if (preventDuplicates != null) this.preventDuplicates = preventDuplicates + if (timeOut != null) this.timeOut = timeOut + if (extendedTimeOut != null) this.extendedTimeOut = extendedTimeOut + if (progressBar != null) this.progressBar = progressBar + if (rtl != null) this.rtl = rtl + if (onShown != null) this.onShown = onShown + if (onHidden != null) this.onHidden = onHidden + if (onClick != null) this.onClick = onClick + if (onCloseClick != null) this.onCloseClick = onCloseClick + } +} + +/** + * Toast component object. + */ +object Toast { + + /** + * Shows a success toast. + * @param message a toast message + * @param title a toast title + * @param options toast options + */ + fun success(message: String, title: String? = null, options: ToastOptions? = null) { + show(ToastType.SUCCESS, message, title, options) + } + + /** + * Shows an info toast. + * @param message a toast message + * @param title a toast title + * @param options toast options + */ + fun info(message: String, title: String? = null, options: ToastOptions? = null) { + show(ToastType.INFO, message, title, options) + } + + /** + * Shows a warning toast. + * @param message a toast message + * @param title a toast title + * @param options toast options + */ + fun warning(message: String, title: String? = null, options: ToastOptions? = null) { + show(ToastType.WARNING, message, title, options) + } + + /** + * Shows an error toast. + * @param message a toast message + * @param title a toast title + * @param options toast options + */ + fun error(message: String, title: String? = null, options: ToastOptions? = null) { + show(ToastType.ERROR, message, title, options) + } + + private fun show(type: ToastType, message: String, title: String? = null, options: ToastOptions? = null) { + if (options != null) { + KVManagerToast.toastr[type.type](message, title, options.toJs()) + } else { + KVManagerToast.toastr[type.type](message, title) + } + } + +} diff --git a/kvision-modules/kvision-toast/webpack.config.d/bootstrap.js b/kvision-modules/kvision-toast/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-toast/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-toast/webpack.config.d/css.js b/kvision-modules/kvision-toast/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-toast/webpack.config.d/css.js @@ -0,0 +1,2 @@ +config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" }); + diff --git a/kvision-modules/kvision-toast/webpack.config.d/file.js b/kvision-modules/kvision-toast/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-toast/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/settings.gradle.kts b/settings.gradle.kts index 40c12aba..6860d1f8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -48,6 +48,7 @@ include( "kvision-modules:kvision-richtext", "kvision-modules:kvision-tabulator", "kvision-modules:kvision-tabulator-remote", + "kvision-modules:kvision-toast", "kvision-modules:kvision-server-javalin", "kvision-modules:kvision-server-jooby", "kvision-modules:kvision-server-ktor", diff --git a/src/main/resources/css/style.css b/src/main/resources/css/style.css index cae50162..69f4b218 100644 --- a/src/main/resources/css/style.css +++ b/src/main/resources/css/style.css @@ -443,3 +443,28 @@ ul.typeahead > li.active > a { text-decoration: none; background-color: #f8f9fa; } + +#toast-container .toast { + background-color: #030303; + max-width: inherit; +} + +#toast-container .toast-success { + background-color: #51A351; +} + +#toast-container .toast-error { + background-color: #BD362F; +} + +#toast-container .toast-info { + background-color: #2F96B4; +} + +#toast-container .toast-warning { + background-color: #F89406; +} + +#toast-container .toast-progress { + background-color: #000000; +} |