diff options
author | Robert Jaros <rjaros@finn.pl> | 2019-10-03 19:03:21 +0200 |
---|---|---|
committer | Robert Jaros <rjaros@finn.pl> | 2019-10-03 19:03:21 +0200 |
commit | 6b53324c97bfc80ed14dfca6a5dbc879950715b9 (patch) | |
tree | 55c7bb7d06e37470795a93e1f542e51ef3f1ace6 | |
parent | 22a8d5c35db97d65a90b21d97e6835380191845d (diff) | |
download | kvision-6b53324c97bfc80ed14dfca6a5dbc879950715b9.tar.gz kvision-6b53324c97bfc80ed14dfca6a5dbc879950715b9.tar.bz2 kvision-6b53324c97bfc80ed14dfca6a5dbc879950715b9.zip |
Upgrade to Bootstrap 4.
Upgrade to Font Awesome 5.
Restructure modules.
246 files changed, 1535 insertions, 875 deletions
diff --git a/build.gradle b/build.gradle index af9c8ac6..da4ab01a 100644 --- a/build.gradle +++ b/build.gradle @@ -135,7 +135,6 @@ if (!project.gradle.startParameter.taskNames.contains("dokka")) { dependency("snabbdom", "0.7.3") dependency("snabbdom-virtualize", "0.7.0") dependency("jquery-resizable-dom", "0.32.0") - dependency("element-resize-event", "3.0.3") dependency("navigo", "7.1.2") devDependency("karma", "4.3.0") devDependency("karma-chrome-launcher", "3.1.0") @@ -160,23 +159,25 @@ if (!project.gradle.startParameter.taskNames.contains("dokka")) { dokka { includes = ['Module.md'] sourceDirs = files('kvision-modules/kvision-bootstrap/src/main/kotlin', - 'kvision-modules/kvision-select/src/main/kotlin', - 'kvision-modules/kvision-datetime/src/main/kotlin', - 'kvision-modules/kvision-spinner/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-css/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-select/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-datetime/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-spinner/src/main/kotlin', 'kvision-modules/kvision-richtext/src/main/kotlin', - 'kvision-modules/kvision-upload/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-upload/src/main/kotlin', 'kvision-modules/kvision-handlebars/src/main/kotlin', 'kvision-modules/kvision-i18n/src/main/kotlin', 'kvision-modules/kvision-chart/src/main/kotlin', 'kvision-modules/kvision-datacontainer/src/main/kotlin', - 'kvision-modules/kvision-dialog/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-dialog/src/main/kotlin', + 'kvision-modules/kvision-fontawesome/src/main/kotlin', 'kvision-modules/kvision-redux/src/main/kotlin', 'kvision-modules/kvision-redux-kotlin/src/main/kotlin', 'kvision-modules/kvision-moment/src/main/kotlin', 'kvision-modules/kvision-tabulator/src/main/kotlin', 'kvision-modules/kvision-pace/src/main/kotlin', 'kvision-modules/kvision-remote/src/main/kotlin', - 'kvision-modules/kvision-select-remote/src/main/kotlin', + 'kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin', 'kvision-modules/kvision-tabulator-remote/src/main/kotlin', 'kvision-modules/kvision-common/src/main/kotlin', 'kvision-modules/kvision-common-types/src/main/kotlin', diff --git a/kvision-modules/kvision-bootstrap-css/build.gradle b/kvision-modules/kvision-bootstrap-css/build.gradle new file mode 100644 index 00000000..0d47049b --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/build.gradle @@ -0,0 +1,5 @@ +apply from: "../shared.gradle" + +dependencies { + compile project(":kvision-modules:kvision-bootstrap") +} diff --git a/kvision-modules/kvision-bootstrap-css/package.json.d/project.info b/kvision-modules/kvision-bootstrap-css/package.json.d/project.info new file mode 100644 index 00000000..b990974a --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/package.json.d/project.info @@ -0,0 +1,3 @@ +{ + "description": "KVision Bootstrap CSS module" +} diff --git a/kvision-modules/kvision-bootstrap-css/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrapCss.kt b/kvision-modules/kvision-bootstrap-css/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrapCss.kt new file mode 100644 index 00000000..ec131d5d --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrapCss.kt @@ -0,0 +1,35 @@ +/* + * 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 kVManagerBootstrapCssInit = KVManagerBootstrapCss.init() + +/** + * Internal singleton object which initializes and configures KVision Bootstrap CSS module. + */ +internal object KVManagerBootstrapCss { + init { + require("bootstrap/dist/css/bootstrap.min.css") + } + + internal fun init() {} +} diff --git a/kvision-modules/kvision-bootstrap/src/main/resources/css/paper.css b/kvision-modules/kvision-bootstrap-css/src/main/resources/css/paper.css index 1c783608..1c783608 100644 --- a/kvision-modules/kvision-bootstrap/src/main/resources/css/paper.css +++ b/kvision-modules/kvision-bootstrap-css/src/main/resources/css/paper.css diff --git a/kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..32a7c4d0 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js @@ -0,0 +1,4 @@ +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'}); +config.module.rules.push({test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}); diff --git a/kvision-modules/kvision-datetime/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/css.js index 5d710d35..5d710d35 100644 --- a/kvision-modules/kvision-datetime/webpack.config.d/css.js +++ b/kvision-modules/kvision-bootstrap-css/webpack.config.d/css.js diff --git a/kvision-modules/kvision-spinner/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js index bf5a1a20..bf5a1a20 100644 --- a/kvision-modules/kvision-spinner/webpack.config.d/jquery.js +++ b/kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js diff --git a/kvision-modules/kvision-datetime/build.gradle b/kvision-modules/kvision-bootstrap-datetime/build.gradle index b853d2f4..fb440934 100644 --- a/kvision-modules/kvision-datetime/build.gradle +++ b/kvision-modules/kvision-bootstrap-datetime/build.gradle @@ -1,5 +1,9 @@ apply from: "../shared.gradle" +dependencies { + compile project(":kvision-modules:kvision-bootstrap") +} + kotlinFrontend { npm { diff --git a/kvision-modules/kvision-datetime/package.json.d/project.info b/kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info index 3d332806..3d332806 100644 --- a/kvision-modules/kvision-datetime/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info diff --git a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt index 4cc71c8b..41f8620f 100644 --- a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt @@ -26,15 +26,9 @@ internal val kVManagerDatetimeInit = KVManagerDatetime.init() /** * Internal singleton object which initializes and configures KVision datetime module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerDatetime { - fun init() {} - - private val bootstrapDateTimePickerCss = try { + init { require("bootstrap-datetime-picker/css/bootstrap-datetimepicker.min.css") - } catch (e: Throwable) { - } - private val bootstrapDateTimePicker = try { require("bootstrap-datetime-picker/js/bootstrap-datetimepicker.min.js") require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js") require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js") @@ -75,7 +69,7 @@ internal object KVManagerDatetime { require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js") require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js") require("./js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt index 3d32fd8c..7fb35057 100644 --- a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt @@ -26,7 +26,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.DateFormControl import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn import kotlin.js.Date @@ -165,21 +165,21 @@ open class DateTime( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt index a375ef35..66cb6cc0 100644 --- a/kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt @@ -28,6 +28,7 @@ import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.i18n.I18n import pl.treksoft.kvision.types.toDateF import pl.treksoft.kvision.types.toStringF @@ -94,6 +95,10 @@ open class DateTimeInput( */ override var size: InputSize? by refreshOnUpdate() /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() + /** * Day of the week start. 0 (Sunday) to 6 (Saturday). */ var weekStart by refreshOnUpdate(0) { refreshDatePicker() } @@ -128,6 +133,9 @@ open class DateTimeInput( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js index a43b4739..a43b4739 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js index c840d6f0..c840d6f0 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js index 3bc7e273..3bc7e273 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js index b46bd54f..b46bd54f 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js index d3137a2d..d3137a2d 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js index 318cd5cf..318cd5cf 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js index 30d9a34a..30d9a34a 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js index 52a19060..52a19060 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js index 882378f3..882378f3 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js index cbbdc9a7..cbbdc9a7 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js index bbf3c207..bbf3c207 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js index 95eb4a8d..95eb4a8d 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js index f9194cbd..f9194cbd 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js index 1060a4a7..1060a4a7 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js index f85540fa..f85540fa 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js index 5de9fe9e..5de9fe9e 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js index cedee4db..cedee4db 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js index feef4a3b..feef4a3b 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js index 9944c6d7..9944c6d7 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js index c00a0499..c00a0499 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js index 3a2d3b9b..3a2d3b9b 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js index d4595eff..d4595eff 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js index adeb6cb6..adeb6cb6 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js index 917243c4..917243c4 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js index f9b3c774..f9b3c774 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js index 26a2cc0e..26a2cc0e 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js index a2fd01a6..a2fd01a6 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js index a28fa031..a28fa031 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js index 36e33a0b..36e33a0b 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js index 12fc7422..12fc7422 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js index 1d307416..1d307416 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js index 166034ef..166034ef 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js index a7569c6f..a7569c6f 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js index 57c819f9..57c819f9 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js index 3e9db3e6..3e9db3e6 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js index 20caf251..20caf251 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js index acf1495a..acf1495a 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js index a7e58bdf..a7e58bdf 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js index 050125ad..050125ad 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js index 8cdb4df2..8cdb4df2 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js index 8adc129a..8adc129a 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js index 0130c94c..0130c94c 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js index 1687a1dc..1687a1dc 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js index 4b3a9e0a..4b3a9e0a 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js index f84ba548..f84ba548 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js diff --git a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js index 66ac5a01..66ac5a01 100644 --- a/kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt index 13c8531b..13c8531b 100644 --- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt index 877cf650..877cf650 100644 --- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt diff --git a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt index b5e393bb..eba3ef74 100644 --- a/kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt @@ -52,7 +52,7 @@ class DateTimeSpec : DomSpec { ) ti.validatorError = "Validation Error" assertEqualsHtml( - "<div class=\"form-group has-error\"><label class=\"control-label\" for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" type=\"text\" placeholder=\"place\" name=\"name\" disabled=\"disabled\" value=\"$datastr\"><span class=\"help-block small\">Validation Error</span></div>", + "<div class=\"form-group text-danger\"><label class=\"control-label\" for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" type=\"text\" placeholder=\"place\" name=\"name\" disabled=\"disabled\" value=\"$datastr\"><span class=\"help-block small\">Validation Error</span></div>", element?.innerHTML, "Should render correct date time input form control with validation error" ) diff --git a/kvision-modules/kvision-select/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/css.js index 5d710d35..5d710d35 100644 --- a/kvision-modules/kvision-select/webpack.config.d/css.js +++ b/kvision-modules/kvision-bootstrap-datetime/webpack.config.d/css.js diff --git a/kvision-modules/kvision-dialog/build.gradle b/kvision-modules/kvision-bootstrap-dialog/build.gradle index 4aaef76d..652d14d6 100644 --- a/kvision-modules/kvision-dialog/build.gradle +++ b/kvision-modules/kvision-bootstrap-dialog/build.gradle @@ -1,5 +1,6 @@ apply from: "../shared.gradle" dependencies { + compile project(":kvision-modules:kvision-bootstrap") compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" } diff --git a/kvision-modules/kvision-dialog/package.json.d/project.info b/kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info index 416cd4a7..416cd4a7 100644 --- a/kvision-modules/kvision-dialog/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info diff --git a/kvision-modules/kvision-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt b/kvision-modules/kvision-bootstrap-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt index e67a6f17..e67a6f17 100644 --- a/kvision-modules/kvision-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt +++ b/kvision-modules/kvision-bootstrap-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt diff --git a/kvision-modules/kvision-select-remote/build.gradle b/kvision-modules/kvision-bootstrap-select-remote/build.gradle index 739c7a53..7a4dc8fa 100644 --- a/kvision-modules/kvision-select-remote/build.gradle +++ b/kvision-modules/kvision-bootstrap-select-remote/build.gradle @@ -1,6 +1,6 @@ apply from: "../shared.gradle" dependencies { - compile project(":kvision-modules:kvision-select") + compile project(":kvision-modules:kvision-bootstrap-select") compile project(":kvision-modules:kvision-remote") } diff --git a/kvision-modules/kvision-select-remote/package.json.d/project.info b/kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info index 5685d581..5685d581 100644 --- a/kvision-modules/kvision-select-remote/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info diff --git a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt index ea9d369b..de823280 100644 --- a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt +++ b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt @@ -26,7 +26,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.remote.KVServiceManager @@ -155,21 +155,21 @@ open class SelectRemote<T : Any>( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt index 4c891d30..4c891d30 100644 --- a/kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt +++ b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt diff --git a/kvision-modules/kvision-select/build.gradle b/kvision-modules/kvision-bootstrap-select/build.gradle index f8fcbc8a..83bcd627 100644 --- a/kvision-modules/kvision-select/build.gradle +++ b/kvision-modules/kvision-bootstrap-select/build.gradle @@ -1,5 +1,9 @@ apply from: "../shared.gradle" +dependencies { + compile project(":kvision-modules:kvision-bootstrap") +} + kotlinFrontend { npm { diff --git a/kvision-modules/kvision-select/package.json.d/project.info b/kvision-modules/kvision-bootstrap-select/package.json.d/project.info index 80e675b0..80e675b0 100644 --- a/kvision-modules/kvision-select/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-select/package.json.d/project.info diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt index e2c556c1..3617c417 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt @@ -26,27 +26,15 @@ internal val kVManagerSelectInit = KVManagerSelect.init() /** * Internal singleton object which initializes and configures KVision select module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerSelect { internal const val AJAX_REQUEST_DELAY = 300 internal const val KVNULL = "#kvnull" - fun init() {} - - private val bootstrapSelectCss = try { + init { require("bootstrap-select/dist/css/bootstrap-select.min.css") - } catch (e: Throwable) { - } - private val bootstrapSelect = try { require("bootstrap-select/dist/js/bootstrap-select.min.js") require("./js/locales/bootstrap-select/bootstrap-select-i18n.min.js") - } catch (e: Throwable) { - } - private val bootstrapSelectAjaxCss = try { require("ajax-bootstrap-select/dist/css/ajax-bootstrap-select.min.css") - } catch (e: Throwable) { - } - private val bootstrapSelectAjax = try { require("ajax-bootstrap-select/dist/js/ajax-bootstrap-select.min.js") require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js") require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js") @@ -59,7 +47,7 @@ internal object KVManagerSelect { require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js") require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js") require("./js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt index c088f68d..c088f68d 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt index db8a5b3b..4b2505d2 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -176,21 +176,21 @@ open class Select( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt index e0a49326..84eccaf7 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt @@ -30,6 +30,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.html.ButtonStyle import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.asString @@ -128,6 +129,10 @@ open class SelectInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() init { setChildrenFromOptions() @@ -228,6 +233,9 @@ open class SelectInput( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() cl.add("selectpicker" to true) + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt index 3f07a9bf..3f07a9bf 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt diff --git a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt index 3977776b..91c269a8 100644 --- a/kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt @@ -91,11 +91,7 @@ open class SelectOption( sn.add("data-subtext" to translate(it)) } icon?.let { - if (it.startsWith("fa-")) { - sn.add("data-icon" to "fa $it") - } else { - sn.add("data-icon" to "glyphicon-$it") - } + sn.add("data-icon" to it) } if (disabled) { sn.add("disabled" to "disabled") diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js index 08b38207..08b38207 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js index 8b130b97..8b130b97 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js index bbe3fe45..bbe3fe45 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js index 1d86582f..1d86582f 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js index b30deb3e..b30deb3e 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js index 23a9a348..23a9a348 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js index 2fd5299b..2fd5299b 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js index 6c6a16f2..6c6a16f2 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js index f104f491..f104f491 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js index 2a6e743d..2a6e743d 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js index aa6d4d06..aa6d4d06 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js index 6af588f4..6af588f4 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js diff --git a/kvision-modules/kvision-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js index 4428d3c0..4428d3c0 100644 --- a/kvision-modules/kvision-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js +++ b/kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt index 13c8531b..13c8531b 100644 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt index bfd93900..bfd93900 100644 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt index 33ccc843..33ccc843 100644 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt index 33c36576..33c36576 100644 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt diff --git a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt index 9eddff81..9eddff81 100644 --- a/kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt +++ b/kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt diff --git a/kvision-modules/kvision-spinner/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-select/webpack.config.d/css.js index 5d710d35..5d710d35 100644 --- a/kvision-modules/kvision-spinner/webpack.config.d/css.js +++ b/kvision-modules/kvision-bootstrap-select/webpack.config.d/css.js diff --git a/kvision-modules/kvision-spinner/build.gradle b/kvision-modules/kvision-bootstrap-spinner/build.gradle index 0c3a2940..02d4e9e5 100644 --- a/kvision-modules/kvision-spinner/build.gradle +++ b/kvision-modules/kvision-bootstrap-spinner/build.gradle @@ -1,5 +1,9 @@ apply from: "../shared.gradle" +dependencies { + compile project(":kvision-modules:kvision-bootstrap") +} + kotlinFrontend { npm { diff --git a/kvision-modules/kvision-spinner/package.json.d/project.info b/kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info index fb0c7956..fb0c7956 100644 --- a/kvision-modules/kvision-spinner/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info diff --git a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt index ca4d3764..de406845 100644 --- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt @@ -26,17 +26,11 @@ internal val kVManagerSpinnerInit = KVManagerSpinner.init() /** * Internal singleton object which initializes and configures KVision spinner module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerSpinner { - fun init() {} - - private val bootstrapTouchspinCss = try { + init { require("bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.css") - } catch (e: Throwable) { - } - private val bootstrapTouchspin = try { require("bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.js") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt index 31c6ceb8..afe085d0 100644 --- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt @@ -25,7 +25,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.NumberFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -167,21 +167,21 @@ open class Spinner( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt index 18df26fa..d760f34b 100644 --- a/kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt @@ -29,6 +29,7 @@ import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.utils.obj /** @@ -153,6 +154,10 @@ open class SpinnerInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() private var siblings: JQuery? = null @@ -162,6 +167,9 @@ open class SpinnerInput( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } @@ -281,8 +289,8 @@ open class SpinnerInput( this.verticalbuttons = verticalbuttons this.forcestepdivisibility = forceType.value if (verticalbuttons) { - this.verticalup = "<i class=\"fa fa-caret-up\"></i>" - this.verticaldown = "<i class=\"fa fa-caret-down\"></i>" + this.verticalup = "<i class=\"fas fa-caret-up\"></i>" + this.verticaldown = "<i class=\"fas fa-caret-down\"></i>" } this.buttondown_class = "btn btn-default" this.buttonup_class = "btn btn-default" diff --git a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt index 13c8531b..13c8531b 100644 --- a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt diff --git a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt index 467e48db..467e48db 100644 --- a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt diff --git a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt index 928fe0b1..ead19d86 100644 --- a/kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt @@ -49,7 +49,7 @@ class SpinnerSpec : DomSpec { ) ti.validatorError = "Validation Error" assertEqualsHtml( - "<div class=\"form-group has-error\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"input-group kv-spinner-btn-vertical\"><span><div class=\"input-group bootstrap-touchspin bootstrap-touchspin-injected\"><input class=\"form-control\" id=\"$id\" type=\"text\" value=\"13\" placeholder=\"place\" name=\"name\" disabled=\"disabled\"><span class=\"input-group-btn-vertical\"><button class=\"btn btn-default bootstrap-touchspin-up \" type=\"button\"><i class=\"fa fa-caret-up\"></i></button><button class=\"btn btn-default bootstrap-touchspin-down \" type=\"button\"><i class=\"fa fa-caret-down\"></i></button></span></div></span></div><span class=\"help-block small\">Validation Error</span></div>", + "<div class=\"form-group text-danger\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"input-group kv-spinner-btn-vertical\"><span><div class=\"input-group bootstrap-touchspin bootstrap-touchspin-injected\"><input class=\"form-control\" id=\"$id\" type=\"text\" value=\"13\" placeholder=\"place\" name=\"name\" disabled=\"disabled\"><span class=\"input-group-btn-vertical\"><button class=\"btn btn-default bootstrap-touchspin-up \" type=\"button\"><i class=\"fa fa-caret-up\"></i></button><button class=\"btn btn-default bootstrap-touchspin-down \" type=\"button\"><i class=\"fa fa-caret-down\"></i></button></span></div></span></div><span class=\"help-block small\">Validation Error</span></div>", element?.innerHTML, "Should render correct spinner input form control with validation error" ) diff --git a/kvision-modules/kvision-upload/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/css.js index 5d710d35..5d710d35 100644 --- a/kvision-modules/kvision-upload/webpack.config.d/css.js +++ b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/css.js diff --git a/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js new file mode 100644 index 00000000..bf5a1a20 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js @@ -0,0 +1,5 @@ +config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" +})); diff --git a/kvision-modules/kvision-upload/build.gradle b/kvision-modules/kvision-bootstrap-upload/build.gradle index 2a843308..a0dfa950 100644 --- a/kvision-modules/kvision-upload/build.gradle +++ b/kvision-modules/kvision-bootstrap-upload/build.gradle @@ -1,6 +1,7 @@ apply from: "../shared.gradle" dependencies { + compile project(":kvision-modules:kvision-bootstrap") compile "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion" } diff --git a/kvision-modules/kvision-upload/package.json.d/project.info b/kvision-modules/kvision-bootstrap-upload/package.json.d/project.info index d789d81b..d789d81b 100644 --- a/kvision-modules/kvision-upload/package.json.d/project.info +++ b/kvision-modules/kvision-bootstrap-upload/package.json.d/project.info diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt index af0950eb..f3370743 100644 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt @@ -26,19 +26,11 @@ internal val kVManagerUploadInit = KVManagerUpload.init() /** * Internal singleton object which initializes and configures KVision upload module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerUpload { - fun init() {} - private val bootstrapFileinputCss = try { + init { require("bootstrap-fileinput/css/fileinput.min.css") - } catch (e: Throwable) { - } - private val bootstrapFileinputCssFa = try { require("bootstrap-fileinput/themes/explorer-fa/theme.min.css") - } catch (e: Throwable) { - } - private val bootstrapFileinput = try { require("bootstrap-fileinput") require("./js/locales/bootstrap-fileinput/ar.js") require("./js/locales/bootstrap-fileinput/az.js") @@ -76,11 +68,8 @@ internal object KVManagerUpload { require("./js/locales/bootstrap-fileinput/uk.js") require("./js/locales/bootstrap-fileinput/vi.js") require("./js/locales/bootstrap-fileinput/zh.js") - } catch (e: Throwable) { - } - private val bootstrapFileinputFa = try { require("bootstrap-fileinput/themes/explorer-fa/theme.min.js") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt index 971ce186..bd931127 100644 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt @@ -26,7 +26,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.KFilesFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.types.KFile @@ -208,21 +208,21 @@ open class Upload( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt index 21073e61..71e00ede 100644 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt @@ -31,6 +31,7 @@ import pl.treksoft.kvision.form.Form import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.FormPanel import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.i18n.I18n import pl.treksoft.kvision.types.KFile import pl.treksoft.kvision.utils.getContent @@ -135,6 +136,10 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla * The size of the input (currently not working) */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() private val nativeFiles: MutableMap<KFile, File> = mutableMapOf() @@ -144,6 +149,9 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt index bdae5091..bdae5091 100644 --- a/kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js index 92d32d28..92d32d28 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js index 5a9c6440..5a9c6440 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js index cf75d1ab..cf75d1ab 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js index 16514535..16514535 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js index 685da85d..685da85d 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js index f5e8b723..f5e8b723 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js index 11a13892..11a13892 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js index 56ee854b..56ee854b 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js index 170eba1f..170eba1f 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js index 569e7ee5..569e7ee5 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js index 50b15477..50b15477 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js index 609099c4..609099c4 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js index 19317b54..19317b54 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js index 81a77042..81a77042 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js index a2ba90be..a2ba90be 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js index cea7de35..cea7de35 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js index 534815fb..534815fb 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js index cc2bab23..cc2bab23 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js index 73ee7663..73ee7663 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js index 3decd7fa..3decd7fa 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js index c6c0a230..c6c0a230 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js index 0190dd73..0190dd73 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js index 82c34cc4..82c34cc4 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js index 91f36c94..91f36c94 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js index df3f3dc4..df3f3dc4 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js index 773bb1bd..773bb1bd 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js index e19a0ed2..e19a0ed2 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js index 157ac84c..157ac84c 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js index 419b1761..419b1761 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js index d31b85bd..d31b85bd 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js index 71c5ff7a..71c5ff7a 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js index 28d67e9a..28d67e9a 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js index 490d7d61..490d7d61 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js index 038b1d99..038b1d99 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js index 7a2d0460..7a2d0460 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js index 1fe6a383..1fe6a383 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js index d1b7f3a1..d1b7f3a1 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js index c2c57168..c2c57168 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js index 7d140b5e..7d140b5e 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js index 49f7710f..49f7710f 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js diff --git a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js index 469fa380..469fa380 100644 --- a/kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js +++ b/kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js diff --git a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt index 13c8531b..13c8531b 100644 --- a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt diff --git a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt index de7a9315..de7a9315 100644 --- a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt diff --git a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt index 92078153..92078153 100644 --- a/kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt diff --git a/kvision-modules/kvision-bootstrap-upload/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-bootstrap-upload/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-upload/webpack.config.d/file.js b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js index a5c7b5da..a5c7b5da 100644 --- a/kvision-modules/kvision-upload/webpack.config.d/file.js +++ b/kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js diff --git a/kvision-modules/kvision-bootstrap/build.gradle b/kvision-modules/kvision-bootstrap/build.gradle index 2f8efeb8..34aa8bb0 100644 --- a/kvision-modules/kvision-bootstrap/build.gradle +++ b/kvision-modules/kvision-bootstrap/build.gradle @@ -3,12 +3,9 @@ apply from: "../shared.gradle" kotlinFrontend { npm { - dependency("popper.js", "1.15.0") dependency("bootstrap", "4.3.1") - dependency("font-awesome", "4.7.0") - dependency("font-awesome-webpack-4", "1.0.0") dependency("awesome-bootstrap-checkbox", "1.0.1") - dependency("bootstrap-vertical-tabs", "1.2.2") + dependency("element-resize-event", "3.0.3") } } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrap.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrap.kt index 678ad33e..1a650117 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrap.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrap.kt @@ -21,38 +21,43 @@ */ package pl.treksoft.kvision -import org.w3c.dom.asList -import kotlin.browser.document +import pl.treksoft.kvision.core.Component +import pl.treksoft.kvision.utils.isIE11 + +internal val kVManagerBootstrapInit = KVManagerBootstrap.init() /** * Internal singleton object which initializes and configures KVision Bootstrap module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerBootstrap { - private val links = document.getElementsByTagName("link") - private val bootstrapWebpack = try { - val bootswatch = links.asList().find { it.getAttribute("href")?.contains("bootstrap.min.css") ?: false } - require("bootstrap") - if (bootswatch != null) { - if (bootswatch.getAttribute("href")?.contains("/paper/") == true) { - require("./css/paper.css") + init { + require("bootstrap/dist/js/bootstrap.bundle.min.js") + require("awesome-bootstrap-checkbox") + require("bootstrap-vertical-tabs") + require("./css/kvbootstrap.css") + } + + private val elementResizeEvent = require("element-resize-event") + + @Suppress("UnsafeCastFromDynamic") + internal fun setResizeEvent(component: Component, callback: () -> Unit) { + if (!isIE11()) { + component.getElement()?.let { + elementResizeEvent(it, callback) } - } else { - require("bootstrap/dist/css/bootstrap.min.css") } - require("./css/style.css") - } catch (e: Throwable) { - } - private val fontAwesomeWebpack = try { - require("font-awesome-webpack-4") - } catch (e: Throwable) { } - private val awesomeBootstrapCheckbox = try { - require("awesome-bootstrap-checkbox") - } catch (e: Throwable) { - } - private val bootstrapVerticalTabsCss = try { - require("bootstrap-vertical-tabs") - } catch (e: Throwable) { + + @Suppress("UnsafeCastFromDynamic") + internal fun clearResizeEvent(component: Component) { + if (!isIE11()) { + if (component.getElement()?.asDynamic()?.__resizeTrigger__?.contentDocument != null) { + component.getElement()?.let { + elementResizeEvent.unbind(it) + } + } + } } + + internal fun init() {} } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/core/Component.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/core/Component.kt new file mode 100644 index 00000000..c35ee9fb --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/core/Component.kt @@ -0,0 +1,133 @@ +/* + * 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.core + +enum class BsBorder(internal val className: String) { + BORDER("border"), + BORDERTOP("border-top"), + BORDERBOTTOM("border-bottom"), + BORDERRIGHT("border-right"), + BORDERLEFT("border-left"), + BORDER_0("border-0"), + BORDERTOP_0("border-top-0"), + BORDERBOTTOM_0("border-bottom-0"), + BORDERRIGHT_0("border-right-0"), + BORDERLEFT_0("border-left-0"), + BORDERPRIMARY("border-primary"), + BORDERSECONDARY("border-secondary"), + BORDERSUCCESS("border-success"), + BORDERDANGER("border-danger"), + BORDERWARNING("border-warning"), + BORDERINFO("border-info"), + BORDERLIGHT("border-light"), + BORDERDARK("border-dark"), + BORDERWHITE("border-white") +} + +fun Component.addBsBorder(vararg bsBorder: BsBorder) { + bsBorder.forEach { + this.addCssClass(it.className) + } +} + +fun Component.removeBsBorder(vararg bsBorder: BsBorder) { + bsBorder.forEach { + this.removeCssClass(it.className) + } +} + +enum class BsRounded(internal val className: String) { + ROUNDED("rounded"), + ROUNDEDTOP("rounded-top"), + ROUNDEDBOTTOM("rounded-bottom"), + ROUNDEDLEFT("rounded-left"), + ROUNDEDRIGHT("rounded-right"), + ROUNDEDCIRCLE("rounded-circle"), + ROUNDEDPILL("rounded-pill"), + ROUNDEDLG("rounded-lg"), + ROUNDEDSM("rounded-sm") +} + +fun Component.addBsRounded(vararg bsRounded: BsRounded) { + bsRounded.forEach { + this.addCssClass(it.className) + } +} + +fun Component.removeBsRounded(vararg bsRounded: BsRounded) { + bsRounded.forEach { + this.removeCssClass(it.className) + } +} + +fun Component.addBsClearfix() { + this.addCssClass("clearfix") +} + +fun Component.removeBsClearfix() { + this.removeCssClass("clearfix") +} + +enum class BsColor(internal val className: String) { + PRIMARY("text-primary"), + SECONDARY("text-secondary"), + SUCCESS("text-success"), + DANGER("text-danger"), + WARNING("text-warning"), + INFO("text-info"), + LIGHT("text-light"), + DARK("text-dark"), + WHITE("text-white"), + BODY("text-body"), + MUTED("text-muted"), + BLACK50("text-black-50"), + WHITE50("text-white-50") +} + +fun Component.addBsColor(bsColor: BsColor) { + this.addCssClass(bsColor.className) +} + +fun Component.removeBsColor(bsColor: BsColor) { + this.removeCssClass(bsColor.className) +} + +enum class BsBgColor(internal val className: String) { + PRIMARY("bg-primary"), + SECONDARY("bg-secondary"), + SUCCESS("bg-success"), + DANGER("bg-danger"), + WARNING("bg-warning"), + INFO("bg-info"), + LIGHT("bg-light"), + DARK("bg-dark"), + WHITE("bg-white"), + TRANSPARENT("bg-transparent") +} + +fun Component.addBsBgColor(bsBgColor: BsBgColor) { + this.addCssClass(bsBgColor.className) +} + +fun Component.removeBsBgColor(bsBgColor: BsBgColor) { + this.removeCssClass(bsBgColor.className) +} diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt index 5fac0494..4e20de81 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt @@ -24,8 +24,7 @@ package pl.treksoft.kvision.dropdown import org.w3c.dom.events.MouseEvent import pl.treksoft.kvision.core.Display import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.html.ListTag -import pl.treksoft.kvision.html.ListType +import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.utils.px @@ -41,7 +40,7 @@ open class ContextMenu( element: Widget? = null, protected val fixedPosition: Boolean = false, classes: Set<String> = setOf(), init: (ContextMenu.() -> Unit)? = null -) : ListTag(ListType.UL, classes = classes + "dropdown-menu") { +) : Div(classes = classes + "dropdown-menu") { init { @Suppress("LeakingThis") @@ -82,6 +81,21 @@ open class ContextMenu( const val DEFAULT_FIXED_POS_Y = 5 /** + * Sets context menu for the current widget. + * @param contextMenu a context menu + * @return current widget + */ + fun Widget.setContextMenu(contextMenu: ContextMenu): Widget { + this.setEventListener<Widget> { + contextmenu = { e: MouseEvent -> + e.preventDefault() + contextMenu.positionMenu(e) + } + } + return this + } + + /** * DSL builder extension function. * * It takes the same parameters as the constructor of the built component. diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt index a521fe95..9862b322 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt @@ -22,20 +22,17 @@ package pl.treksoft.kvision.dropdown import com.github.snabbdom.VNode -import pl.treksoft.kvision.KVManager import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.CssSize +import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.html.Button import pl.treksoft.kvision.html.ButtonStyle import pl.treksoft.kvision.html.ButtonType +import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.html.Link -import pl.treksoft.kvision.html.ListTag -import pl.treksoft.kvision.html.ListType -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.obj @@ -49,6 +46,16 @@ enum class DD(val option: String) { } /** + * Dropdown directions. + */ +enum class Direction(internal val direction: String) { + DROPDOWN("dropdown"), + DROPUP("dropup"), + DROPLEFT("dropleft"), + DROPRIGHT("dropright") +} + +/** * Bootstrap dropdown component. * * @constructor @@ -56,16 +63,17 @@ enum class DD(val option: String) { * @param elements an optional list of link elements (special options from [DD] enum class can be used as values) * @param icon the icon of the dropdown button * @param style the style of the dropdown button + * @param direction the direction of the dropdown * @param disabled determines if the component is disabled on start * @param forNavbar determines if the component will be used in a navbar - * @param withCaret determines if the dropdown button renders caret + * @param forDropDown determines if the component will be used in a dropdown * @param classes a set of CSS class names */ @Suppress("TooManyFunctions") open class DropDown( text: String, elements: List<StringPair>? = null, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, disabled: Boolean = false, val forNavbar: Boolean = false, - withCaret: Boolean = true, classes: Set<String> = setOf() + style: ButtonStyle = ButtonStyle.PRIMARY, direction: Direction = Direction.DROPDOWN, disabled: Boolean = false, + val forNavbar: Boolean = false, val forDropDown: Boolean = false, classes: Set<String> = setOf() ) : SimplePanel(classes) { /** * Label of the dropdown button. @@ -125,9 +133,9 @@ open class DropDown( button.image = value } /** - * Determines if the dropdown is showing upwards. + * The direction of the dropdown. */ - var dropup by refreshOnUpdate(false) + var direction by refreshOnUpdate(direction) /** * Width of the dropdown button. */ @@ -140,15 +148,18 @@ open class DropDown( private val idc = "kv_dropdown_$counter" internal val button: DropDownButton = DropDownButton( - idc, text, icon, style, - disabled, forNavbar, withCaret, setOf("dropdown") + idc, text, icon, style, disabled, forNavbar, forDropDown ) fun buttonId() = button.id - internal val list: DropDownListTag = DropDownListTag(idc, setOf("dropdown-menu")) + internal val list: DropDownDiv = DropDownDiv(idc) init { + if (forDropDown) { + this.style = ButtonStyle.LIGHT + this.direction = Direction.DROPRIGHT + } setChildrenFromElements() this.addInternal(button) this.addInternal(list) @@ -195,11 +206,12 @@ open class DropDown( DD.HEADER.option -> Header(it.first) DD.SEPARATOR.option -> Separator() DD.DISABLED.option -> { - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(Link(it.first)) - tag + Link(it.first, "javascript:void(0)", classes = setOf("dropdown-item", "disabled")).apply { + tabindex = -1 + setAttribute("aria-disabled", "true") + } } - else -> Link(it.first, it.second) + else -> Link(it.first, it.second, classes = setOf("dropdown-item")) } } list.addAll(c) @@ -224,10 +236,8 @@ open class DropDown( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() - if (dropup) - cl.add("dropup" to true) - else - cl.add("dropdown" to true) + if (forNavbar) cl.add("nav-item" to true) + cl.add(direction.direction to true) return cl } @@ -235,7 +245,7 @@ open class DropDown( * Toggles dropdown visibility. */ open fun toggle() { - this.list.getElementJQueryD()?.dropdown("toggle") + this.button.getElementJQuery()?.click() } companion object { @@ -248,8 +258,9 @@ open class DropDown( */ fun Container.dropDown( text: String, elements: List<StringPair>? = null, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, disabled: Boolean = false, forNavbar: Boolean = false, - withCaret: Boolean = true, classes: Set<String> = setOf(), init: (DropDown.() -> Unit)? = null + style: ButtonStyle = ButtonStyle.PRIMARY, direction: Direction = Direction.DROPDOWN, + disabled: Boolean = false, forNavbar: Boolean = false, forDropDown: Boolean = false, + classes: Set<String> = setOf(), init: (DropDown.() -> Unit)? = null ): DropDown { val dropDown = DropDown( @@ -257,14 +268,84 @@ open class DropDown( elements, icon, style, + direction, disabled, forNavbar, - withCaret, + forDropDown, classes ).apply { init?.invoke(this) } this.add(dropDown) return dropDown } + + /** + * DSL builder extension function for a link in a dropdown list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun DropDown.ddLink( + label: String, url: String? = null, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = Link(label, url, icon, image, classes + "dropdown-item").apply { + init?.invoke(this) + } + this.add(link) + return link + } + + /** + * DSL builder extension function for a link in a context menu list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun ContextMenu.cmLink( + label: String, url: String? = null, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = Link(label, url, icon, image, classes + "dropdown-item").apply { + init?.invoke(this) + } + this.add(link) + return link + } + + /** + * DSL builder extension function for a disabled link in a dropdown list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun DropDown.ddLinkDisabled( + label: String, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = Link(label, "javascript:void(0)", icon, image, classes + "dropdown-item" + "disabled").apply { + tabindex = -1 + setAttribute("aria-disabled", "true") + init?.invoke(this) + } + this.add(link) + return link + } + + /** + * DSL builder extension function for a disabled link in a context menu list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun ContextMenu.cmLinkDisabled( + label: String, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = Link(label, "javascript:void(0)", icon, image, classes + "dropdown-item" + "disabled").apply { + tabindex = -1 + setAttribute("aria-disabled", "true") + init?.invoke(this) + } + this.add(link) + return link + } + } } @@ -272,35 +353,33 @@ internal class DropDownButton( id: String, text: String, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, + style: ButtonStyle = ButtonStyle.PRIMARY, disabled: Boolean = false, val forNavbar: Boolean = false, - val withCaret: Boolean = true, + val forDropDown: Boolean = false, classes: Set<String> = setOf() ) : Button(text, icon, style, ButtonType.BUTTON, disabled, classes) { init { this.id = id - this.role = "button" + if (!forNavbar && !forDropDown) this.role = "button" setInternalEventListener<DropDownButton> { click = { e -> - if (parent?.parent is ContextMenu) e.asDynamic().dropDownCM = true + if (parent?.parent is ContextMenu) { + e.asDynamic().dropDownCM = true + } else if (forDropDown || forNavbar) { + (parent as DropDown).list.getElementJQuery()?.toggle() + e.stopPropagation() + } } } } override fun render(): VNode { val text = createLabelWithIcon(text, icon, image) - return if (forNavbar) { - if (withCaret) { - val textWithCarret = text.toMutableList() - textWithCarret.add(" ") - textWithCarret.add(KVManager.virtualize("<span class='caret'></span>")) - render("a", textWithCarret.toTypedArray()) - } else { - render("a", text) - } + return if (forNavbar || forDropDown) { + render("a", text) } else { render("button", text) } @@ -308,25 +387,30 @@ internal class DropDownButton( override fun getSnClass(): List<StringBoolPair> { return if (forNavbar) { - listOf("dropdown" to true) + listOf("nav-link" to true, "dropdown-toggle" to true) + } else if (forDropDown) { + super.getSnClass() + listOf("dropdown-item" to true, "dropdown-toggle" to true) } else { - super.getSnClass() + super.getSnClass() + ("dropdown-toggle" to true) } } override fun getSnAttrs(): List<StringPair> { - return super.getSnAttrs() + listOf( + val inherited = super.getSnAttrs() + return if (forDropDown || forNavbar) { + inherited.filter { it.first != "type" } + } else { + inherited + } + listOf( "data-toggle" to "dropdown", "aria-haspopup" to "true", "aria-expanded" to "false", "href" to "#" ) } } -internal class DropDownListTag(private val ariaId: String, classes: Set<String> = setOf()) : ListTag( - ListType.UL, null, - false, classes +internal class DropDownDiv(private val ariaId: String) : Div( + null, false, null, setOf("dropdown-menu") ) { - override fun getSnAttrs(): List<StringPair> { return super.getSnAttrs() + listOf("aria-labelledby" to ariaId) } diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt index 4cee7b7b..13e0b2e4 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt @@ -21,7 +21,6 @@ */ package pl.treksoft.kvision.dropdown -import pl.treksoft.kvision.html.ListTag import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag @@ -33,7 +32,7 @@ import pl.treksoft.kvision.html.Tag * @param classes a set of CSS class names */ open class Header(content: String? = null, classes: Set<String> = setOf()) : - Tag(TAG.LI, content, classes = classes + "dropdown-header") { + Tag(TAG.H6, content, classes = classes + "dropdown-header") { companion object { @@ -42,7 +41,7 @@ open class Header(content: String? = null, classes: Set<String> = setOf()) : * * It takes the same parameters as the constructor of the built component. */ - fun ListTag.header(content: String? = null, classes: Set<String> = setOf()): Header { + fun ContextMenu.header(content: String? = null, classes: Set<String> = setOf()): Header { val header = Header(content, classes) this.add(header) return header diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt index c682b0e9..dd2344bd 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt @@ -21,9 +21,7 @@ */ package pl.treksoft.kvision.dropdown -import pl.treksoft.kvision.html.ListTag -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.html.Div /** * Menu separator component. @@ -31,11 +29,7 @@ import pl.treksoft.kvision.html.Tag * @constructor * @param classes a set of CSS class names */ -open class Separator(classes: Set<String> = setOf()) : Tag(TAG.LI, classes = classes + "divider") { - - init { - role = "separator" - } +open class Separator(classes: Set<String> = setOf()) : Div(classes = classes + "dropdown-divider") { companion object { /** @@ -43,7 +37,7 @@ open class Separator(classes: Set<String> = setOf()) : Tag(TAG.LI, classes = cla * * It takes the same parameters as the constructor of the built component. */ - fun ListTag.separator(classes: Set<String> = setOf()): Separator { + fun ContextMenu.separator(classes: Set<String> = setOf()): Separator { val separator = Separator(classes) this.add(separator) return separator diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt index 5f5a1a80..5f5a1a80 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt index 5f0440a6..5f0440a6 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt index e16ca87e..e16ca87e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt index 7f120f73..08fc7aa8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt @@ -31,6 +31,8 @@ import pl.treksoft.kvision.html.Button import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.panel.Root.Companion.addModal +import pl.treksoft.kvision.panel.Root.Companion.removeModal import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.obj @@ -38,6 +40,7 @@ import pl.treksoft.kvision.utils.obj * Modal window sizes. */ enum class ModalSize(val className: String) { + XLARGE("modal-xl"), LARGE("modal-lg"), SMALL("modal-sm") } @@ -101,7 +104,7 @@ open class Modal( * Internal property. */ protected val closeIcon = CloseIcon() - private val captionTag = Tag(TAG.H4, caption, classes = setOf("modal-title")) + private val captionTag = Tag(TAG.H5, caption, classes = setOf("modal-title")) /** * @suppress * Internal property. @@ -112,6 +115,7 @@ open class Modal( init { this.hide() this.role = "dialog" + this.tabindex = -1 this.addInternal(dialog) val content = SimplePanel(setOf("modal-content")) dialog.role = "document" @@ -122,14 +126,14 @@ open class Modal( hide() } } - header.add(closeIcon) header.add(captionTag) + header.add(closeIcon) checkHeaderVisibility() content.add(header) content.add(body) content.add(footer) @Suppress("LeakingThis") - modals.add(this) + addModal(this) @Suppress("LeakingThis") init?.invoke(this) } @@ -195,12 +199,6 @@ open class Modal( return this } - override fun getSnAttrs(): List<StringPair> { - val pr = super.getSnAttrs().toMutableList() - pr.add("tabindex" to "-1") - return pr - } - override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() cl.add("modal" to true) @@ -267,11 +265,7 @@ open class Modal( } override fun dispose() { - modals.remove(this) - } - - companion object { - internal var modals = mutableListOf<Modal>() + removeModal(this) } } diff --git a/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt index 3bbb6eed..e0da480d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt @@ -21,9 +21,10 @@ */ package pl.treksoft.kvision.navbar +import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.html.Div +import pl.treksoft.kvision.html.Link /** * The Bootstrap Nav container. @@ -34,7 +35,7 @@ import pl.treksoft.kvision.html.Tag * @param init an initializer extension function */ open class Nav(rightAlign: Boolean = false, classes: Set<String> = setOf(), init: (Nav.() -> Unit)? = null) : - Tag(TAG.UL, classes = classes) { + Div(classes = classes) { /** * Determines if the nav is aligned to the right. @@ -48,10 +49,9 @@ open class Nav(rightAlign: Boolean = false, classes: Set<String> = setOf(), init override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() - cl.add("nav" to true) cl.add("navbar-nav" to true) if (rightAlign) { - cl.add("navbar-right" to true) + cl.add("ml-auto" to true) } return cl } @@ -69,5 +69,42 @@ open class Nav(rightAlign: Boolean = false, classes: Set<String> = setOf(), init this.add(nav) return nav } + + + /** + * DSL builder extension function for a link in a nav list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Nav.navLink( + label: String, url: String? = null, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = Link(label, url, icon, image, classes + "nav-item" + "nav-link").apply { + init?.invoke(this) + } + this.add(link) + return link + } + + /** + * DSL builder extension function for a disabled link in a nav list. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Nav.navLinkDisabled( + label: String, icon: String? = null, image: ResString? = null, + classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null + ): Link { + val link = + Link(label, "javascript:void(0)", icon, image, classes + "nav-item" + "nav-link" + "disabled").apply { + tabindex = -1 + setAttribute("aria-disabled", "true") + init?.invoke(this) + } + this.add(link) + return link + } + } } diff --git a/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt index 725c298e..45454cc8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt @@ -48,11 +48,9 @@ open class NavForm(rightAlign: Boolean = false, classes: Set<String> = setOf(), override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() - cl.add("navbar-form" to true) + cl.add("form-inline" to true) if (rightAlign) { - cl.add("navbar-right" to true) - } else { - cl.add("navbar-left" to true) + cl.add("ml-auto" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt index 2080bb8e..34a9dbe2 100644 --- a/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt @@ -22,22 +22,42 @@ package pl.treksoft.kvision.navbar import com.github.snabbdom.VNode +import pl.treksoft.kvision.core.BsBgColor import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.html.Link -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag.Companion.tag +import pl.treksoft.kvision.html.Span +import pl.treksoft.kvision.html.Span.Companion.span import pl.treksoft.kvision.panel.SimplePanel /** * Navbar types. */ enum class NavbarType(internal val navbarType: String) { - FIXEDTOP("navbar-fixed-top"), - FIXEDBOTTOM("navbar-fixed-bottom"), - STATICTOP("navbar-static-top") + FIXEDTOP("fixed-top"), + FIXEDBOTTOM("fixed-bottom"), + STICKYTOP("sticky-top") +} + +/** + * Navbar colors. + */ +enum class NavbarColor(internal val navbarColor: String) { + LIGHT("navbar-light"), + DARK("navbar-dark") +} + +/** + * Navbar responsive behavior. + */ +enum class NavbarExpand(internal val navbarExpand: String) { + ALWAYS("navbar-expand"), + XL("navbar-expand-xl"), + LG("navbar-expand-lg"), + MD("navbar-expand-md"), + SM("navbar-expand-sm"), } /** @@ -46,14 +66,18 @@ enum class NavbarType(internal val navbarType: String) { * @constructor * @param label the navbar label * @param type the navbar type - * @param inverted determines if the navbar is inverted + * @param expand the navbar responsive behavior + * @param nColor the navbar color + * @param bgColor the navbar background color * @param classes a set of CSS class names * @param init an initializer extension function */ open class Navbar( label: String? = null, type: NavbarType? = null, - inverted: Boolean = false, + expand: NavbarExpand? = NavbarExpand.LG, + nColor: NavbarColor = NavbarColor.LIGHT, + bgColor: BsBgColor = BsBgColor.LIGHT, classes: Set<String> = setOf(), init: (Navbar.() -> Unit)? = null ) : SimplePanel(classes) { @@ -76,9 +100,17 @@ open class Navbar( */ var type by refreshOnUpdate(type) /** - * Determines if the navbar is inverted. + * The navbar responsive behavior. */ - var inverted by refreshOnUpdate(inverted) + var expand by refreshOnUpdate(expand) + /** + * The navbar color. + */ + var nColor by refreshOnUpdate(nColor) + /** + * The navbar background color. + */ + var bgColor by refreshOnUpdate(bgColor) private val idc = "kv_navbar_$counter" @@ -88,14 +120,9 @@ open class Navbar( } init { - val c = SimplePanel(setOf("container-fluid")) { - simplePanel(setOf("navbar-header")) { - add(NavbarButton(idc)) - add(brandLink) - } - add(container) - } - addInternal(c) + addInternal(brandLink) + addInternal(NavbarButton(idc)) + addInternal(container) if (label == null) brandLink.hide() counter++ @Suppress("LeakingThis") @@ -136,11 +163,11 @@ open class Navbar( type?.let { cl.add(it.navbarType to true) } - if (inverted) { - cl.add("navbar-inverse" to true) - } else { - cl.add("navbar-default" to true) + expand?.let { + cl.add(it.navbarExpand to true) } + cl.add(nColor.navbarColor to true) + cl.add(bgColor.className to true) return cl } @@ -155,13 +182,21 @@ open class Navbar( fun Container.navbar( label: String? = null, type: NavbarType? = null, - inverted: Boolean = false, + expand: NavbarExpand? = NavbarExpand.LG, + nColor: NavbarColor = NavbarColor.LIGHT, + bgColor: BsBgColor = BsBgColor.LIGHT, classes: Set<String> = setOf(), init: (Navbar.() -> Unit)? = null ): Navbar { - val navbar = Navbar(label, type, inverted, classes, init) + val navbar = Navbar(label, type, expand, nColor, bgColor, classes, init) this.add(navbar) return navbar } + + fun Navbar.navText(label: String, classes: Set<String> = setOf()): Span { + val text = Span(label, classes = classes + "navbar-text") + this.add(text) + return text + } } } @@ -170,14 +205,11 @@ open class Navbar( * Internal component. * The Bootstrap Navbar header button. */ -internal class NavbarButton(private val idc: String, toggle: String = "Toggle navigation") : - SimplePanel(setOf("navbar-toggle", "collapsed")) { +internal class NavbarButton(private val idc: String, private val toggle: String = "Toggle navigation") : + SimplePanel(setOf("navbar-toggler")) { init { - tag(TAG.SPAN, toggle, classes = setOf("sr-only")) - tag(TAG.SPAN, classes = setOf("icon-bar")) - tag(TAG.SPAN, classes = setOf("icon-bar")) - tag(TAG.SPAN, classes = setOf("icon-bar")) + span(classes = setOf("navbar-toggler-icon")) } override fun render(): VNode { @@ -189,7 +221,9 @@ internal class NavbarButton(private val idc: String, toggle: String = "Toggle na "type" to "button", "data-toggle" to "collapse", "data-target" to "#$idc", - "aria-expanded" to "false" + "aria-controls" to idc, + "aria-expanded" to "false", + "aria-label" to toggle ) } } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt index 7a5b07d6..2ff6fa19 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt @@ -32,10 +32,10 @@ import pl.treksoft.kvision.html.Tag * Bootstrap grid sizes. */ enum class GridSize(internal val size: String) { - XS("xs"), SM("sm"), MD("md"), - LG("lg") + LG("lg"), + XL("xs") } internal const val MAX_COLUMNS = 12 @@ -82,10 +82,10 @@ open class ResponsiveGridPanel( * @return this container */ open fun add(child: Component, col: Int, row: Int, size: Int = 0, offset: Int = 0): ResponsiveGridPanel { - val cRow = maxOf(row, 0) - val cCol = maxOf(col, 0) - if (row > rows - 1) rows = cRow + 1 - if (col > cols - 1) cols = cCol + 1 + val cRow = maxOf(row, 1) + val cCol = maxOf(col, 1) + if (cRow > rows) rows = cRow + if (cCol > cols) cols = cCol map.getOrPut(cRow) { mutableMapOf() }[cCol] = WidgetParam(child, size, offset) if (size > 0 || offset > 0) auto = false refreshRowContainers() @@ -128,11 +128,11 @@ open class ResponsiveGridPanel( singleRender { clearRowContainers() val num = MAX_COLUMNS / cols - for (i in 0 until rows) { + for (i in 1..rows) { val rowContainer = SimplePanel(setOf("row")) val row = map[i] if (row != null) { - (0 until cols).map { row[it] }.forEach { wp -> + (1..cols).map { row[it] }.forEach { wp -> if (auto) { val widget = wp?.widget?.let { WidgetWrapper(it, setOf("col-" + gridSize.size + "-" + num)) @@ -146,7 +146,7 @@ open class ResponsiveGridPanel( val s = if (wp.size > 0) wp.size else num val widget = WidgetWrapper(wp.widget, setOf("col-" + gridSize.size + "-" + s)) if (wp.offset > 0) { - widget.addCssClass("col-" + gridSize.size + "-offset-" + wp.offset) + widget.addCssClass("offset-" + gridSize.size + "-" + wp.offset) } align?.let { widget.addCssClass(it.className) diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt index f620f2b0..2009e4fc 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt @@ -82,18 +82,18 @@ open class TabPanel( set(value) { if (content.activeIndex != value) { content.activeIndex = value - nav.children.forEach { - it.removeCssClass("active") - } - if (content.activeIndex in nav.children.indices) { - nav.children[content.activeIndex].addCssClass("active") - } + } + nav.getChildren().forEach { + (it as Tag).getChildren().firstOrNull()?.removeCssClass("active") + } + if (content.activeIndex in nav.getChildren().indices) { + (nav.getChildren()[content.activeIndex] as Tag).getChildren().firstOrNull()?.addCssClass("active") } } private val navClasses = when (tabPosition) { TabPosition.TOP -> if (scrollableTabs) setOf("nav", "nav-tabs", "tabs-top") else setOf("nav", "nav-tabs") - TabPosition.LEFT -> setOf("nav", "nav-tabs", "tabs-left") - TabPosition.RIGHT -> setOf("nav", "nav-tabs", "tabs-right") + TabPosition.LEFT -> setOf("nav", "nav-tabs", "tabs-left", "flex-column") + TabPosition.RIGHT -> setOf("nav", "nav-tabs", "tabs-right", "flex-column") } private var nav = Tag(TAG.UL, classes = navClasses) private var content = StackPanel(false) @@ -107,16 +107,18 @@ open class TabPanel( this.addInternal(content) } TabPosition.LEFT -> { - this.addCssClass("clearfix") + this.addSurroundingCssClass("container-fluid") + this.addCssClass("row") val sizes = calculateSideClasses() - this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "col-nopadding"))) - this.addInternal(WidgetWrapper(content, setOf(sizes.second, "col-nopadding"))) + this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "pl-0", "pr-0"))) + this.addInternal(WidgetWrapper(content, setOf(sizes.second, "pl-0", "pr-0"))) } TabPosition.RIGHT -> { - this.addCssClass("clearfix") + this.addSurroundingCssClass("container-fluid") + this.addCssClass("row") val sizes = calculateSideClasses() - this.addInternal(WidgetWrapper(content, setOf(sizes.second, "col-nopadding"))) - this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "col-nopadding"))) + this.addInternal(WidgetWrapper(content, setOf(sizes.second, "pl-0", "pr-0"))) + this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "pl-0", "pr-0"))) } } @Suppress("LeakingThis") @@ -125,12 +127,12 @@ open class TabPanel( private fun calculateSideClasses(): Pair<String, String> { return when (sideTabSize) { - SideTabSize.SIZE_1 -> Pair("col-xs-1", "col-xs-11") - SideTabSize.SIZE_2 -> Pair("col-xs-2", "col-xs-10") - SideTabSize.SIZE_3 -> Pair("col-xs-3", "col-xs-9") - SideTabSize.SIZE_4 -> Pair("col-xs-4", "col-xs-8") - SideTabSize.SIZE_5 -> Pair("col-xs-5", "col-xs-7") - SideTabSize.SIZE_6 -> Pair("col-xs-6", "col-xs-6") + SideTabSize.SIZE_1 -> Pair("col-sm-1", "col-sm-11") + SideTabSize.SIZE_2 -> Pair("col-sm-2", "col-sm-10") + SideTabSize.SIZE_3 -> Pair("col-sm-3", "col-sm-9") + SideTabSize.SIZE_4 -> Pair("col-sm-4", "col-sm-8") + SideTabSize.SIZE_5 -> Pair("col-sm-5", "col-sm-7") + SideTabSize.SIZE_6 -> Pair("col-sm-6", "col-sm-6") } } @@ -150,15 +152,14 @@ open class TabPanel( ): TabPanel { val currentIndex = counter++ childrenMap[currentIndex] = panel - val tag = Tag(TAG.LI) { - role = "presentation" - link(title, "#", icon, image) { + val tag = Tag(TAG.LI, classes = setOf("nav-item")) { + link(title, "#", icon, image, classes = setOf("nav-link")) { if (closable) { - cicon("remove") { + cicon("fas fa-times") { addCssClass("kv-tab-close") setEventListener<Icon> { click = { e -> - val actIndex = this@TabPanel.content.children.indexOf(childrenMap[currentIndex]) + val actIndex = this@TabPanel.content.getChildren().indexOf(childrenMap[currentIndex]) e.asDynamic().data = actIndex @Suppress("UnsafeCastFromDynamic") if (this@TabPanel.dispatchEvent( @@ -176,7 +177,7 @@ open class TabPanel( } setEventListener { click = { e -> - activeIndex = this@TabPanel.content.children.indexOf(childrenMap[currentIndex]) + activeIndex = this@TabPanel.content.getChildren().indexOf(childrenMap[currentIndex]) e.preventDefault() if (route != null) { routing.navigate(route) @@ -185,13 +186,15 @@ open class TabPanel( } } nav.add(tag) - if (nav.children.size == 1) { - tag.addCssClass("active") + if (nav.getChildren().size == 1) { + tag.getChildren().firstOrNull()?.addCssClass("active") activeIndex = 0 } content.add(panel) if (route != null) { - routing.on(route, { _ -> activeIndex = this@TabPanel.content.children.indexOf(childrenMap[currentIndex]) }) + routing.on( + route, + { _ -> activeIndex = this@TabPanel.content.getChildren().indexOf(childrenMap[currentIndex]) }) .resolve() } return this @@ -201,11 +204,11 @@ open class TabPanel( * Removes tab at given index. */ open fun removeTab(index: Int): TabPanel { - nav.remove(nav.children[index]) - childrenMap.filter { it.value == content.children[index] }.keys.firstOrNull()?.let { + nav.remove(nav.getChildren()[index]) + childrenMap.filter { it.value == content.getChildren()[index] }.keys.firstOrNull()?.let { childrenMap.remove(it) } - content.remove(content.children[index]) + content.remove(content.getChildren()[index]) activeIndex = content.activeIndex return this } @@ -220,7 +223,7 @@ open class TabPanel( } override fun remove(child: Component): TabPanel { - val index = content.children.indexOf(child) + val index = content.getChildren().indexOf(child) return removeTab(index) } @@ -229,7 +232,7 @@ open class TabPanel( * @param index tab index */ open fun getChildComponent(index: Int): Component? { - return content.children[index] + return content.getChildren()[index] } /** @@ -237,7 +240,7 @@ open class TabPanel( * @param index tab index */ open fun getNavComponent(index: Int): Tag? { - return nav.children[index] as? Tag + return nav.getChildren()[index] as? Tag } override fun removeAll(): TabPanel { diff --git a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt index 4d0f4b93..4d0f4b93 100644 --- a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt index 256d15d7..256d15d7 100644 --- a/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt index ae57fc90..2aef9e63 100644 --- a/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt @@ -24,22 +24,14 @@ package pl.treksoft.kvision.toolbar import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.px /** * Button group sizes. */ enum class ButtonGroupSize(internal val className: String) { LARGE("btn-group-lg"), - SMALL("btn-group-sm"), - XSMALL("btn-group-xs") -} - -/** - * Button group styles. - */ -enum class ButtonGroupStyle(internal val className: String) { - VERTICAL("btn-group-vertical"), - JUSTIFIED("btn-group-justified") + SMALL("btn-group-sm") } /** @@ -47,12 +39,12 @@ enum class ButtonGroupStyle(internal val className: String) { * * @constructor * @param size button group size - * @param style button group style + * @param vertical determines if button group is aligned vertically * @param classes a set of CSS class names * @param init an initializer extension function */ open class ButtonGroup( - size: ButtonGroupSize? = null, style: ButtonGroupStyle? = null, + size: ButtonGroupSize? = null, vertical: Boolean = false, classes: Set<String> = setOf(), init: (ButtonGroup.() -> Unit)? = null ) : SimplePanel(classes) { @@ -61,9 +53,9 @@ open class ButtonGroup( */ var size by refreshOnUpdate(size) /** - * Button group style. + * Vertical alignment. */ - var style by refreshOnUpdate(style) + var vertical by refreshOnUpdate(vertical) init { role = "group" @@ -73,12 +65,11 @@ open class ButtonGroup( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() - if (style != ButtonGroupStyle.VERTICAL) { + if (vertical) { + cl.add("btn-group-vertical" to true) + } else { cl.add("btn-group" to true) } - style?.let { - cl.add(it.className to true) - } size?.let { cl.add(it.className to true) } @@ -92,10 +83,25 @@ open class ButtonGroup( * It takes the same parameters as the constructor of the built component. */ fun Container.buttonGroup( - size: ButtonGroupSize? = null, style: ButtonGroupStyle? = null, + size: ButtonGroupSize? = null, vertical: Boolean = false, + classes: Set<String> = setOf(), init: (ButtonGroup.() -> Unit)? = null + ): ButtonGroup { + val group = ButtonGroup(size, vertical, classes).apply { init?.invoke(this) } + this.add(group) + return group + } + /** + * DSL builder extension function for toolbar. + * + * It creates button groups with size and vertical parameters of the toolbar. + */ + fun Toolbar.buttonGroup( classes: Set<String> = setOf(), init: (ButtonGroup.() -> Unit)? = null ): ButtonGroup { - val group = ButtonGroup(size, style, classes).apply { init?.invoke(this) } + val group = ButtonGroup(this.size, this.vertical, classes).apply { + marginRight = this@buttonGroup.spacing.px + init?.invoke(this) + } this.add(group) return group } diff --git a/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt index f348f4cc..13ed8972 100644 --- a/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt @@ -28,10 +28,14 @@ import pl.treksoft.kvision.panel.SimplePanel * The Bootstrap toolbar. * * @constructor + * @param size button groups size + * @param spacing the spacing between button groups + * @param vertical determines if button groups are aligned vertically * @param classes a set of CSS class names * @param init an initializer extension function */ open class Toolbar( + val size: ButtonGroupSize? = null, val spacing: Int = 5, val vertical: Boolean = false, classes: Set<String> = setOf(), init: (Toolbar.() -> Unit)? = null ) : SimplePanel(classes + "btn-toolbar") { @@ -48,9 +52,10 @@ open class Toolbar( * It takes the same parameters as the constructor of the built component. */ fun Container.toolbar( + size: ButtonGroupSize? = null, spacing: Int = 2, vertical: Boolean = false, classes: Set<String> = setOf(), init: (Toolbar.() -> Unit)? = null ): Toolbar { - val toolbar = Toolbar(classes).apply { init?.invoke(this) } + val toolbar = Toolbar(size, spacing, vertical, classes).apply { init?.invoke(this) } this.add(toolbar) return toolbar } diff --git a/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt index a3ceaf61..a3ceaf61 100644 --- a/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt index c8034d09..c8034d09 100644 --- a/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt diff --git a/src/main/kotlin/pl/treksoft/kvision/window/Window.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt index 3816de3a..83473858 100644 --- a/src/main/kotlin/pl/treksoft/kvision/window/Window.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt @@ -25,6 +25,7 @@ import com.github.snabbdom.VNode import org.w3c.dom.events.Event import org.w3c.dom.events.MouseEvent import pl.treksoft.kvision.KVManager +import pl.treksoft.kvision.KVManagerBootstrap import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.CssSize @@ -166,7 +167,8 @@ open class Window( private val closeIcon = CloseIcon() private val maximizeIcon = MaximizeIcon() private val minimizeIcon = MinimizeIcon() - private val captionTag = Tag(TAG.H4, caption, classes = setOf("modal-title")) + private val captionTag = Tag(TAG.H5, caption, classes = setOf("modal-title")) + private val iconsContainer = SimplePanel(setOf("kv-window-icons-container")) private val windowIcon = Icon(icon ?: "").apply { addCssClass("window-icon") visible = (icon != null && icon != "") @@ -184,19 +186,22 @@ open class Window( width = contentWidth @Suppress("LeakingThis") zIndex = ++zIndexCounter - closeIcon.visible = closeButton - closeIcon.setEventListener { + header.add(captionTag) + captionTag.add(windowIcon) + header.add(iconsContainer) + minimizeIcon.visible = minimizeButton + minimizeIcon.setEventListener { click = { _ -> @Suppress("UnsafeCastFromDynamic") - if (this@Window.dispatchEvent("closeWindow", obj {}) != false) { - close() + if (this@Window.dispatchEvent("minimizeWindow", obj {}) != false) { + toggleMinimize() } } mousedown = { e -> e.stopPropagation() } } - header.add(closeIcon) + iconsContainer.add(minimizeIcon) maximizeIcon.visible = maximizeButton maximizeIcon.setEventListener { click = { _ -> @@ -209,22 +214,20 @@ open class Window( e.stopPropagation() } } - header.add(maximizeIcon) - minimizeIcon.visible = minimizeButton - minimizeIcon.setEventListener { + iconsContainer.add(maximizeIcon) + closeIcon.visible = closeButton + closeIcon.setEventListener { click = { _ -> @Suppress("UnsafeCastFromDynamic") - if (this@Window.dispatchEvent("minimizeWindow", obj {}) != false) { - toggleMinimize() + if (this@Window.dispatchEvent("closeWindow", obj {}) != false) { + close() } } mousedown = { e -> e.stopPropagation() } } - header.add(minimizeIcon) - header.add(captionTag) - captionTag.add(windowIcon) + iconsContainer.add(closeIcon) checkHeaderVisibility() addInternal(header) addInternal(content) @@ -309,7 +312,7 @@ open class Window( if (isResizable) { if (!isResizeEvent) { isResizeEvent = true - KVManager.setResizeEvent(this) { + KVManagerBootstrap.setResizeEvent(this) { val eid = getElementJQuery()?.attr("id") if (isResizable && eid == id) { val outerWidth = (getElementJQuery()?.outerWidth()?.toInt() ?: 0) @@ -330,7 +333,7 @@ open class Window( } } } else if (isResizeEvent) { - KVManager.clearResizeEvent(this) + KVManagerBootstrap.clearResizeEvent(this) isResizeEvent = false } } @@ -365,7 +368,7 @@ open class Window( override fun afterDestroy() { if (isResizeEvent) { - KVManager.clearResizeEvent(this) + KVManagerBootstrap.clearResizeEvent(this) isResizeEvent = false } } diff --git a/kvision-modules/kvision-bootstrap/src/main/resources/css/kvbootstrap.css b/kvision-modules/kvision-bootstrap/src/main/resources/css/kvbootstrap.css new file mode 100644 index 00000000..1a16b41f --- /dev/null +++ b/kvision-modules/kvision-bootstrap/src/main/resources/css/kvbootstrap.css @@ -0,0 +1,291 @@ +/* + +.bootstrap-touchspin .input-group-btn-vertical> .input-sm { + padding: 7px 10px; + height: 6px; +} + +.bootstrap-touchspin .input-group-btn-vertical> .input-lg { + height: 24px; +} + +.kv-spinner-btn-none .input-group-btn-vertical { + display: none; +} + +.kv-spinner-btn-none .form-control { + border-radius: 4px !important; +} + +.kv-spinner-btn-vertical .form-control { + border-radius: 4px 0px 0px 4px !important; +}*/ + +.form-check { + padding-left: 0.5rem; +} + +.form-check-input.form-control-sm, .form-check-input.form-control-lg { + height: inherit; +} + +.kv-radiogroup-inline label.control-label { + vertical-align: top; + margin-right: .75rem; + margin-bottom: 0px; +} +.row.kv-radiogroup-inline label.control-label { + margin-right: 0px; +} + +.row.kv-radiogroup-inline .kv-radiogroup-container, .row.kv-radiogroup .kv-radiogroup-container { + margin-left: -15px; +} + +.kv-radiogroup-inline .kv-radiogroup-container { + display: inline-flex; +} + +.kv-radiogroup-container.is-invalid~.invalid-feedback { + display: block; +} + +.form-check-inline { + margin-left: 3px; +} + +.form-check-inline.form-check { + padding-left: 0px; +} + +.form-horizontal.container-fluid { + width: inherit; +} + +.form-inline .form-group { + margin-right: 6px; +} + +.form-inline .form-group .control-label { + margin-right: 6px; +} + +.form-inline .form-check.form-group { + margin-left: 6px; +} + +.kv-form-condensed .form-group { + margin-bottom: 0.5rem; +} + +.kv-window.modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0,0,0,.5); + box-shadow: 0 5px 15px rgba(0,0,0,.5); + border-radius: 0px; +} + +.kv-window .modal-header { + height: 40px; + padding: 5px 15px 5px 15px; + align-items: center; +} + +.kv-window .modal-header button.close { + width: 24px; + height: 24px; + margin: 0px; + padding: 0px; +} + +.kv-window .modal-header .modal-title { + white-space: nowrap; +} + +.kv-window .modal-header .window-icon { + margin-right: 6px; +} + +.kv-window .kv-window-icons-container { + display: flex; +} + +.kv-preview-thumb .btn, .kv-zoom-actions .btn, .file-zoom-dialog .floating-buttons .btn { + padding: 5px 8px; +} + +.file-drop-zone.clickable:hover { + border: 1px dashed #999; +} + +.file-drop-zone.clickable:focus { + border: 1px solid #5acde2; +} + +.nav.tabs-top { + flex-wrap: nowrap; +} + +ul.tabs-top { + overflow-x: auto; + overflow-y: hidden; + display: flex; +} + +ul.tabs-top > li { + float:none; + flex-shrink: 0; +} + +.kv-tab-close { + margin-left: 10px; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: 0.2; +} + +.kv-tab-close:hover, .kv-tab-close:focus { + cursor: pointer; + filter: alpha(opacity=50); + opacity: 0.5; +} + +/*select.form-control, .tabulator-row .tabulator-cell.tabulator-editing select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: transparent none no-repeat; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAKCAYAAABblxXYAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wUKFyIn4IjqJgAAAENJREFUKM/l0LERACEQQlGsiTa2px1aokGugNNAx8wfMy8AeLoBALYjaTqoKkga2+gKPgF/2Q7JkEx359oftu+C7/UBCUIcVQz0PvcAAAAASUVORK5CYII='); + background-position: right center; + cursor: pointer; +} + +select.form-control:hover { + background-color: #e6e6e6; +} + +select.form-control option { + background-color: white; +} + +select.input-sm { + line-height: inherit; +}*/ + +.abc-checkbox input[type="checkbox"]:checked+label::after, +.abc-checkbox input[type="radio"]:checked+label::after { + font-family: "Font Awesome 5 Pro", "Font Awesome 5 Free"; + content: "\f00c"; + font-weight: 900; +} + +.abc-checkbox label::before { + top: 0px; +} +.abc-checkbox label::after { + top: 0px; +} + +.abc-radio label::before { + top: 0px; +} + +.abc-radio label::after { + top: 3px; +} + +.abc-checkbox.form-check-inline label::before { + top: 2px; +} + +.abc-checkbox.form-check-inline label::after { + top: 2px; +} + +.abc-radio.form-check-inline label::before { + top: 2px; +} + +.abc-radio.form-check-inline label::after { + top: 5px; +} + +.abc-checkbox label.col-form-label-lg::before { + top: 10px; +} +.abc-checkbox label.col-form-label-lg::after { + top: 10px; +} + +.abc-radio label.col-form-label-lg::before { + top: 10px; +} + +.abc-radio label.col-form-label-lg::after { + top: 13px; +} + +.abc-checkbox.form-check-inline label.col-form-label-lg::before { + top: 15px; +} + +.abc-checkbox.form-check-inline label.col-form-label-lg::after { + top: 15px; +} + +.abc-radio.form-check-inline label.col-form-label-lg::before { + top: 15px; +} + +.abc-radio.form-check-inline label.col-form-label-lg::after { + top: 18px; +} + +/*! + * bootstrap-vertical-tabs - v1.2.2 + * https://dbtek.github.io/bootstrap-vertical-tabs + * 2016-12-02 + * Copyright (c) 2016 Ä°smail Demirbilek + * License: MIT + */ +.nav-tabs.tabs-left, .nav-tabs.tabs-right { + border-bottom: none; + padding-top: 2px; +} +.nav-tabs.tabs-left { + border-right: 1px solid #dee2e6; +} +.nav-tabs.tabs-right { + border-left: 1px solid #dee2e6; +} +.nav-tabs.tabs-left>li.nav-item, .nav-tabs.tabs-right>li.nav-item { + float: none; + margin-bottom: 2px; +} +.nav-tabs.tabs-left>li.nav-item { + margin-right: -1px; +} +.nav-tabs.tabs-right>li.nav-item { + margin-left: -1px; +} +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active, +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active:hover, +.nav-tabs.tabs-left>li.nav-item>a.nav-link.active:focus { + border-bottom-color: #dee2e6; + border-right-color: transparent; +} +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active, +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active:hover, +.nav-tabs.tabs-right>li.nav-item>a.nav-link.active:focus { + border-bottom: 1px solid #dee2e6; + border-left-color: transparent; +} +.nav-tabs.tabs-left>li.nav-item>a.nav-link { + border-radius: 4px 0 0 4px; + margin-right: 0; + display:block; +} +.nav-tabs.tabs-right>li.nav-item>a.nav-link { + border-radius: 0 4px 4px 0; + margin-right: 0; +} diff --git a/kvision-modules/kvision-bootstrap/src/main/resources/css/style.css b/kvision-modules/kvision-bootstrap/src/main/resources/css/style.css deleted file mode 100644 index 475a0b85..00000000 --- a/kvision-modules/kvision-bootstrap/src/main/resources/css/style.css +++ /dev/null @@ -1,226 +0,0 @@ -.splitpanel-vertical { - display: flex; - flex-direction: row; - overflow: auto; -} - -.splitpanel-vertical > *:first-child { - max-width: calc(100% - 9px); -} - -.splitpanel-vertical > * { - flex: 0 0 auto; - overflow: auto; -} - -.splitpanel-vertical > *:last-child { - flex: 1 1 auto; - overflow: auto; -} - -.splitpanel-horizontal { - display: flex; - flex-direction: column; - overflow: auto; -} - -.splitpanel-horizontal > *:first-child { - max-height: calc(100% - 9px); -} - -.splitpanel-horizontal > * { - flex: 0 0 auto; - overflow: auto; -} - -.splitpanel-horizontal > *:last-child { - flex: 1 1 auto; - overflow: auto; -} - - -.splitter-vertical { - flex: 0 0 auto; - width: 9px; - background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAhCAQAAABOpSL+AAAAIklEQVR4AWMwbb/PdR+JZDD9f1/oPhI5sgVGBSruc9xHIgGdSQqqQJGkRgAAAABJRU5ErkJggg==') center center no-repeat #cecece; - cursor: col-resize; -} - -.splitter-horizontal { - flex: 0 0 auto; - height: 9px; - background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAICAQAAADdTl4aAAAAIElEQVQoz2MwrTD9TxFsZ7jPcV+IIsjFQAUw6hFqegQA+xzRHT2p7pEAAAAASUVORK5CYII=') center center no-repeat #cecece; - cursor: row-resize; -} - -.trix-control { - overflow-y: auto; -} - -trix-toolbar .trix-button-group { - margin-bottom: 3px; -} - -.form-inline .form-group { - margin-right:6px; -} - -.form-inline .checkbox, .form-inline .radio { - margin-right:6px; -} - -.form-inline .form-group .form-control, .navbar-form .form-group .form-control { - margin-left:6px; -} - -.form-horizontal .checkbox, .form-horizontal .radio { - padding-left: 25px; -} - -.form-inline .form-group trix-editor.form-control { - margin-left: 0px; - width: 100%; -} - -.form-inline .form-group, .form-inline .control-label { - vertical-align: top; -} - -.bootstrap-touchspin .input-group-btn-vertical> .input-sm { - padding: 7px 10px; - height: 6px; -} - -.bootstrap-touchspin .input-group-btn-vertical> .input-lg { - height: 24px; -} - -.kv-spinner-btn-none .input-group-btn-vertical { - display: none; -} - -.kv-spinner-btn-none .form-control { - border-radius: 4px !important; -} - -.kv-spinner-btn-vertical .form-control { - border-radius: 4px 0px 0px 4px !important; -} - -.kv-radiogroup .radio { - margin-top: -5px; -} - -.kv-radiogroup-inline label { - margin-right: 10px; -} - -.kv-radio-checkbox { - padding-left: 7px; -} - -.kv-window { - border-radius: 0px; -} - -.kv-window .modal-header { - height: 40px; - padding: 10px 15px 5px 15px; -} - -.kv-window .modal-header button.close { - width: 21px; -} - -.kv-window .modal-header .modal-title { - white-space: nowrap; -} - -.kv-window .modal-header .window-icon { - display: inline-block; - margin-right: 6px; -} - -ul.dropdown-menu li a { - cursor: pointer; -} - -.col-nopadding { - padding-left: 0; - padding-right: 0; -} - -.kv-preview-thumb .btn, .kv-zoom-actions .btn, .file-zoom-dialog .floating-buttons .btn { - padding: 5px 8px; -} - -.file-drop-zone.clickable:hover { - border: 1px dashed #999; -} - -.file-drop-zone.clickable:focus { - border: 1px solid #5acde2; -} - -ul.tabs-top { - overflow-x: auto; - overflow-y: hidden; - display: flex; -} - -ul.tabs-top > li { - float:none; - flex-shrink: 0; -} - -.kv-tab-close { - margin-left: 10px; - color: #000; - text-shadow: 0 1px 0 #fff; - filter: alpha(opacity=20); - opacity: 0.2; -} - -.kv-tab-close:hover, .kv-tab-close:focus { - cursor: pointer; - filter: alpha(opacity=50); - opacity: 0.5; -} - -select.form-control, .tabulator-row .tabulator-cell.tabulator-editing select { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background: transparent none no-repeat; - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAKCAYAAABblxXYAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wUKFyIn4IjqJgAAAENJREFUKM/l0LERACEQQlGsiTa2px1aokGugNNAx8wfMy8AeLoBALYjaTqoKkga2+gKPgF/2Q7JkEx359oftu+C7/UBCUIcVQz0PvcAAAAASUVORK5CYII='); - background-position: right center; - cursor: pointer; -} - -select.form-control:hover { - background-color: #e6e6e6; -} - -select.form-control option { - background-color: white; -} - -select.input-sm { - line-height: inherit; -} - -.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select { - border: 1px solid #ccc; - border-radius: 4px; -} - -.tabulator-row .tabulator-cell.tabulator-editing input:focus, .tabulator-row .tabulator-cell.tabulator-editing select:focus { - border-color: #66afe9; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); -} - -.tabulator-row .tabulator-cell.tabulator-editing { - border-right: 1px solid #1d68cd !important; - padding: 2px !important; -} diff --git a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt index 35172267..35172267 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt index e75baf9e..e75baf9e 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt index 86607ec7..86607ec7 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt index 40720bcb..40720bcb 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt index 988a706d..988a706d 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt index f38a05f9..f38a05f9 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt index fcdf9860..fcdf9860 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt index 9335562f..9335562f 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt index 2f044987..2f044987 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt index 4aa14230..4aa14230 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt index b324b8ab..b324b8ab 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt diff --git a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt index d41ef05e..d41ef05e 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt +++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt diff --git a/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/KVManagerChart.kt b/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/KVManagerChart.kt index 73a0f2b9..b572d896 100644 --- a/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/KVManagerChart.kt +++ b/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/KVManagerChart.kt @@ -26,13 +26,11 @@ internal val kVManagerChartInit = KVManagerChart.init() /** * Internal singleton object which initializes and configures KVision Chart module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerChart { - fun init() {} - private val chart = try { + init { require("chart.js/dist/Chart.bundle.min.js") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-fontawesome/build.gradle b/kvision-modules/kvision-fontawesome/build.gradle new file mode 100644 index 00000000..82dd1894 --- /dev/null +++ b/kvision-modules/kvision-fontawesome/build.gradle @@ -0,0 +1,9 @@ +apply from: "../shared.gradle" + +kotlinFrontend { + + npm { + dependency("@fortawesome/fontawesome-free", "5.11.2") + } + +} diff --git a/kvision-modules/kvision-fontawesome/package.json.d/project.info b/kvision-modules/kvision-fontawesome/package.json.d/project.info new file mode 100644 index 00000000..0801ee7b --- /dev/null +++ b/kvision-modules/kvision-fontawesome/package.json.d/project.info @@ -0,0 +1,3 @@ +{ + "description": "KVision Font Awesome module" +} diff --git a/kvision-modules/kvision-fontawesome/src/main/kotlin/pl/treksoft/kvision/KVManagerFontAwesome.kt b/kvision-modules/kvision-fontawesome/src/main/kotlin/pl/treksoft/kvision/KVManagerFontAwesome.kt new file mode 100644 index 00000000..f816fb0e --- /dev/null +++ b/kvision-modules/kvision-fontawesome/src/main/kotlin/pl/treksoft/kvision/KVManagerFontAwesome.kt @@ -0,0 +1,35 @@ +/* + * 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 kVManagerFontAwesomeInit = KVManagerFontAwesome.init() + +/** + * Internal singleton object which initializes and configures KVision Font Awesome module. + */ +internal object KVManagerFontAwesome { + init { + require("@fortawesome/fontawesome-free/css/all.min.css") + } + + internal fun init() {} +} diff --git a/kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js b/kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js new file mode 100644 index 00000000..32a7c4d0 --- /dev/null +++ b/kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js @@ -0,0 +1,4 @@ +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'}); +config.module.rules.push({test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml'}); diff --git a/kvision-modules/kvision-fontawesome/webpack.config.d/css.js b/kvision-modules/kvision-fontawesome/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-fontawesome/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-fontawesome/webpack.config.d/jquery.js b/kvision-modules/kvision-fontawesome/webpack.config.d/jquery.js new file mode 100644 index 00000000..bf5a1a20 --- /dev/null +++ b/kvision-modules/kvision-fontawesome/webpack.config.d/jquery.js @@ -0,0 +1,5 @@ +config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" +})); diff --git a/kvision-modules/kvision-handlebars/src/main/kotlin/pl/treksoft/kvision/KVManagerHandlebars.kt b/kvision-modules/kvision-handlebars/src/main/kotlin/pl/treksoft/kvision/KVManagerHandlebars.kt index b2e52bf7..3bc021bc 100644 --- a/kvision-modules/kvision-handlebars/src/main/kotlin/pl/treksoft/kvision/KVManagerHandlebars.kt +++ b/kvision-modules/kvision-handlebars/src/main/kotlin/pl/treksoft/kvision/KVManagerHandlebars.kt @@ -26,13 +26,11 @@ internal val kVManagerHandlebarsInit = KVManagerHandlebars.init() /** * Internal singleton object which initializes and configures KVision handlebars module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerHandlebars { - fun init() {} - private val handlebars = try { + init { require("handlebars/dist/handlebars.runtime.min.js") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-i18n/src/main/kotlin/pl/treksoft/kvision/KVManagerI18n.kt b/kvision-modules/kvision-i18n/src/main/kotlin/pl/treksoft/kvision/KVManagerI18n.kt index 9e24327b..51f24fa4 100644 --- a/kvision-modules/kvision-i18n/src/main/kotlin/pl/treksoft/kvision/KVManagerI18n.kt +++ b/kvision-modules/kvision-i18n/src/main/kotlin/pl/treksoft/kvision/KVManagerI18n.kt @@ -26,13 +26,11 @@ internal val kVManagerI18nInit = KVManagerI18n.init() /** * Internal singleton object which initializes and configures KVision i18n module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerI18n { - fun init() {} - private val jed = try { + init { require("jed") - } catch (e: Throwable) { } + internal fun init() {} } diff --git a/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt b/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt index 330d818d..fe11288b 100644 --- a/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt +++ b/kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt @@ -27,11 +27,11 @@ internal val kVManagerMomentInit = KVManagerMoment.init() /** * Internal singleton object which initializes and configures KVision Moment module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerMoment { - fun init() {} - private val moment = try { + init { require("moment/min/moment-with-locales.js") - } catch (e: Throwable) {} + } + + internal fun init() {} } diff --git a/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt b/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt index 9678d1fa..1a57f871 100644 --- a/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt +++ b/kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt @@ -27,13 +27,11 @@ internal val kVManagerPaceInit = KVManagerPace.init() /** * Internal singleton object which initializes and configures KVision Moment module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerPace { - fun init() { - } - private val pace = try { + init { require("pace-progressbar").default - } catch (e: Throwable) { } + + internal fun init() {} } diff --git a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/KVManagerRedux.kt b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/KVManagerRedux.kt index 346f623d..d86f3a67 100644 --- a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/KVManagerRedux.kt +++ b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/KVManagerRedux.kt @@ -33,18 +33,10 @@ internal val kVManagerReduxInit = KVManagerRedux.init() /** * Internal singleton object which initializes and configures KVision Redux module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerRedux { - fun init() {} - private val redux = try { - require("redux/dist/redux.min.js") - } catch (e: Throwable) { - } - internal val reduxThunk = try { - require("redux-thunk/dist/redux-thunk.min.js").default - } catch (e: Throwable) { - } + private val redux = require("redux/dist/redux.min.js") + internal val reduxThunk = require("redux-thunk/dist/redux-thunk.min.js").default @Suppress("UnsafeCastFromDynamic") internal fun <S, A, R> createStore( @@ -72,4 +64,6 @@ internal object KVManagerRedux { } return composeEnhancers(function1, function2) } + + internal fun init() {} } diff --git a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Profile.kt b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Profile.kt index d5745afe..47026f7f 100644 --- a/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Profile.kt +++ b/kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Profile.kt @@ -22,7 +22,6 @@ package pl.treksoft.kvision.remote import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient /** * A user profile. @@ -38,7 +37,6 @@ actual data class Profile( val remembered: Boolean = false, val clientName: String? = null ) { - @Transient var username: String? get() = attributes["username"] set(value) { @@ -48,7 +46,6 @@ actual data class Profile( attributes.remove("username") } } - @Transient var firstName: String? get() = attributes["first_name"] set(value) { @@ -58,7 +55,6 @@ actual data class Profile( attributes.remove("first_name") } } - @Transient var familyName: String? get() = attributes["family_name"] set(value) { @@ -68,7 +64,6 @@ actual data class Profile( attributes.remove("family_name") } } - @Transient var displayName: String? get() = attributes["display_name"] set(value) { @@ -78,7 +73,6 @@ actual data class Profile( attributes.remove("display_name") } } - @Transient var email: String? get() = attributes["email"] set(value) { @@ -88,7 +82,6 @@ actual data class Profile( attributes.remove("email") } } - @Transient var pictureUrl: String? get() = attributes["picture_url"] set(value) { @@ -98,7 +91,6 @@ actual data class Profile( attributes.remove("picture_url") } } - @Transient var profileUrl: String? get() = attributes["profile_url"] set(value) { diff --git a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/KVManagerRichText.kt b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/KVManagerRichText.kt index c7cd444c..b1b624eb 100644 --- a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/KVManagerRichText.kt +++ b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/KVManagerRichText.kt @@ -30,15 +30,10 @@ internal val kVManagerRichTextInit = KVManagerRichText.init() /** * Internal singleton object which initializes and configures KVision RichText module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerRichText { - fun init() {} - private val trixCss = try { + init { require("trix/dist/trix.css") - } catch (e: Throwable) { - } - private val trix = try { val trix = require("trix") window.asDynamic().Trix = trix trix.config.languages = obj {} @@ -59,6 +54,7 @@ internal object KVManagerRichText { orig() } require("./js/locales/trix/trix.pl.js") - } catch (e: Throwable) { } + + internal fun init() {} } diff --git a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt index 22126797..04a02279 100644 --- a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt +++ b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt @@ -55,7 +55,7 @@ open class RichText( @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) } companion object { diff --git a/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/KVManagerTabulator.kt b/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/KVManagerTabulator.kt index ebd1b9f7..96c084e0 100644 --- a/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/KVManagerTabulator.kt +++ b/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/KVManagerTabulator.kt @@ -26,22 +26,18 @@ internal val kVManagerTabulatorInit = KVManagerTabulator.init() /** * Internal singleton object which initializes and configures KVision Tabulator module. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") internal object KVManagerTabulator { - fun init() {} - private val tabulatorCss = try { - require("tabulator-tables/dist/css/bootstrap/tabulator_bootstrap.min.css") - } catch (e: Throwable) { + init { + require("tabulator-tables/dist/css/bootstrap/tabulator_bootstrap4.min.css") } - private val tabulator = try { - require("tabulator-tables/dist/js/tabulator.min.js") - } catch (e: Throwable) { - } + private val tabulator = require("tabulator-tables/dist/js/tabulator.min.js") @Suppress("UnsafeCastFromDynamic") fun getConstructor(): Any { return tabulator } + + internal fun init() {} } diff --git a/settings.gradle b/settings.gradle index 3fc250ff..316306ce 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,26 +4,28 @@ include 'kvision-modules:kvision-base', 'kvision-modules:kvision-common-remote', 'kvision-modules:kvision-common-types', 'kvision-modules:kvision-bootstrap', -// 'kvision-modules:kvision-select', -// 'kvision-modules:kvision-datetime', -// 'kvision-modules:kvision-spinner', -// 'kvision-modules:kvision-richtext', -// 'kvision-modules:kvision-upload', -// 'kvision-modules:kvision-handlebars', - 'kvision-modules:kvision-i18n' -// 'kvision-modules:kvision-chart', -// 'kvision-modules:kvision-datacontainer', -// 'kvision-modules:kvision-dialog', -// 'kvision-modules:kvision-redux', -// 'kvision-modules:kvision-redux-kotlin', -// 'kvision-modules:kvision-tabulator', -// 'kvision-modules:kvision-moment', -// 'kvision-modules:kvision-pace', -// 'kvision-modules:kvision-remote', -// 'kvision-modules:kvision-select-remote', -// 'kvision-modules:kvision-tabulator-remote', -// 'kvision-modules:kvision-server-jooby', -// 'kvision-modules:kvision-server-ktor', -// 'kvision-modules:kvision-server-spring-boot', -// 'kvision-modules:kvision-electron', -// 'kvision-modules:kvision-cordova' + 'kvision-modules:kvision-bootstrap-css', + 'kvision-modules:kvision-bootstrap-datetime', + 'kvision-modules:kvision-bootstrap-spinner', + 'kvision-modules:kvision-bootstrap-upload', + 'kvision-modules:kvision-bootstrap-select', + 'kvision-modules:kvision-bootstrap-select-remote', + 'kvision-modules:kvision-bootstrap-dialog', + 'kvision-modules:kvision-richtext', + 'kvision-modules:kvision-handlebars', + 'kvision-modules:kvision-i18n', + 'kvision-modules:kvision-chart', + 'kvision-modules:kvision-datacontainer', + 'kvision-modules:kvision-fontawesome', + 'kvision-modules:kvision-redux', + 'kvision-modules:kvision-redux-kotlin', + 'kvision-modules:kvision-tabulator', + 'kvision-modules:kvision-moment', + 'kvision-modules:kvision-pace', + 'kvision-modules:kvision-remote', + 'kvision-modules:kvision-tabulator-remote', + 'kvision-modules:kvision-server-jooby', + 'kvision-modules:kvision-server-ktor', + 'kvision-modules:kvision-server-spring-boot', + 'kvision-modules:kvision-electron', + 'kvision-modules:kvision-cordova' diff --git a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt index d1a4a8be..d3d00851 100644 --- a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt +++ b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt @@ -30,8 +30,6 @@ import com.github.snabbdom.eventListenersModule import com.github.snabbdom.propsModule import com.github.snabbdom.styleModule import org.w3c.dom.HTMLElement -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.utils.isIE11 import kotlin.browser.document import kotlin.dom.clear @@ -44,20 +42,25 @@ external fun require(name: String): dynamic /** * Internal singleton object which initializes and configures KVision framework. */ -@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught", "LargeClass") -internal object KVManager { - private val kvisionBootstrap = try { - require("kvision-bootstrap").pl.treksoft.kvision.KVManagerBootstrap - } catch (e: Throwable) { - } - private val elementResizeEvent = try { - require("element-resize-event") - } catch (e: Throwable) { - } - private val resizable = try { +@Suppress("EmptyCatchBlock", "TooGenericExceptionCaught") +object KVManager { + init { + try { + require("kvision-bootstrap").pl.treksoft.kvision.KVManagerBootstrap + } catch (e: Throwable) { + } + try { + require("kvision-bootstrap-css").pl.treksoft.kvision.KVManagerBootstrapCss + } catch (e: Throwable) { + } + try { + require("kvision-fontawesome").pl.treksoft.kvision.KVManagerFontAwesome + } catch (e: Throwable) { + } + require("./css/style.css") require("jquery-resizable-dom") - } catch (e: Throwable) { } + internal val fecha = require("fecha") private val sdPatch = Snabbdom.init( arrayOf( @@ -81,28 +84,12 @@ internal object KVManager { return sdPatch(oldVNode, newVNode) } + /** + * @suppress + * Internal function. + */ @Suppress("UnsafeCastFromDynamic") - internal fun virtualize(html: String): VNode { + fun virtualize(html: String): VNode { return sdVirtualize(html) } - - @Suppress("UnsafeCastFromDynamic") - internal fun setResizeEvent(component: Component, callback: () -> Unit) { - if (!isIE11()) { - component.getElement()?.let { - elementResizeEvent(it, callback) - } - } - } - - @Suppress("UnsafeCastFromDynamic") - internal fun clearResizeEvent(component: Component) { - if (!isIE11()) { - if (component.getElement()?.asDynamic()?.__resizeTrigger__?.contentDocument != null) { - component.getElement()?.let { - elementResizeEvent.unbind(it) - } - } - } - } } diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index e17d7ba9..24543b1f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -27,11 +27,9 @@ import com.github.snabbdom.h import org.w3c.dom.CustomEventInit import org.w3c.dom.DragEvent import org.w3c.dom.Node -import org.w3c.dom.events.MouseEvent import pl.treksoft.jquery.JQuery import pl.treksoft.jquery.jQuery import pl.treksoft.kvision.KVManager -import pl.treksoft.kvision.dropdown.ContextMenu import pl.treksoft.kvision.i18n.I18n import pl.treksoft.kvision.i18n.I18n.trans import pl.treksoft.kvision.panel.Root @@ -83,6 +81,10 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ var role: String? by refreshOnUpdate() /** + * A tabindex attribute of generated HTML element. + */ + var tabindex: Int? by refreshOnUpdate() + /** * Determines if the current widget is draggable. */ var draggable: Boolean? by refreshOnUpdate() @@ -241,6 +243,9 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component role?.let { snattrs.add("role" to it) } + tabindex?.let { + snattrs.add("tabindex" to it.toString()) + } if (draggable == true) { snattrs.add("draggable" to "true") } @@ -439,7 +444,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun enableTooltip(options: TooltipOptions = TooltipOptions()): Widget { this.tooltipOptions = options - getElementJQueryD()?.tooltip(options.copy(title = options.title?.let { translate(it) }).toJs()) + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip(options.copy(title = options.title?.let { translate(it) }).toJs()) return this } @@ -449,7 +455,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun showTooltip(): Widget { if (this.tooltipOptions != null) { - getElementJQueryD()?.tooltip("show") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("show") } return this } @@ -460,7 +467,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun hideTooltip(): Widget { if (this.tooltipOptions != null) { - getElementJQueryD()?.tooltip("hide") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("hide") } return this } @@ -471,7 +479,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun disableTooltip(): Widget { this.tooltipOptions = null - getElementJQueryD()?.tooltip("destroy") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("dispose") return this } @@ -482,7 +491,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun enablePopover(options: PopoverOptions = PopoverOptions()): Widget { this.popoverOptions = options - getElementJQueryD()?.popover( + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover( options.copy(title = options.title?.let { translate(it) }, content = options.content?.let { translate(it) }).toJs() ) @@ -495,7 +505,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun showPopover(): Widget { if (this.popoverOptions != null) { - getElementJQueryD()?.popover("show") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("show") } return this } @@ -506,7 +517,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun hidePopover(): Widget { if (this.popoverOptions != null) { - getElementJQueryD()?.popover("hide") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("hide") } return this } @@ -517,7 +529,8 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component */ open fun disablePopover(): Widget { this.popoverOptions = null - getElementJQueryD()?.popover("destroy") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("dispose") return this } @@ -624,11 +637,13 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component internal open fun afterInsertInternal(node: VNode) { this.tooltipOptions?.let { @Suppress("UnsafeCastFromDynamic") - getElementJQueryD().tooltip(it.copy(title = it.title?.let { translate(it) }).toJs()) + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip(it.copy(title = it.title?.let { translate(it) }).toJs()) } this.popoverOptions?.let { @Suppress("UnsafeCastFromDynamic") - getElementJQueryD().popover( + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover( it.copy(title = it.title?.let { translate(it) }, content = it.content?.let { translate(it) }).toJs() ) @@ -647,10 +662,12 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component @Suppress("UnsafeCastFromDynamic") internal open fun afterDestroyInternal() { this.tooltipOptions?.let { - getElementJQueryD().tooltip("destroy") + val tooltipFun = getElementJQueryD()?.tooltip + if (tooltipFun != undefined) getElementJQueryD()?.tooltip("dispose") } this.popoverOptions?.let { - getElementJQueryD().popover("destroy") + val popoverFun = getElementJQueryD()?.popover + if (popoverFun != undefined) getElementJQueryD()?.popover("dispose") } } @@ -731,21 +748,6 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component } /** - * Sets context menu for the current widget. - * @param contextMenu a context menu - * @return current widget - */ - open fun setContextMenu(contextMenu: ContextMenu): Widget { - setEventListener<Widget> { - contextmenu = { e: MouseEvent -> - e.preventDefault() - contextMenu.positionMenu(e) - } - } - return this - } - - /** * @suppress * Internal function */ @@ -755,11 +757,7 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component ): Array<out Any> { val translatedLabel = translate(label) return if (icon != null) { - if (icon.startsWith("fa-")) { - arrayOf(KVManager.virtualize("<i class='fa $icon'></i>"), " $translatedLabel") - } else { - arrayOf(KVManager.virtualize("<span class='glyphicon glyphicon-$icon'></span>"), " $translatedLabel") - } + arrayOf(KVManager.virtualize("<i class='$icon'></i>"), " $translatedLabel") } else if (image != null) { arrayOf(KVManager.virtualize("<img src='$image' alt='' />"), " $translatedLabel") } else { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt index 3019fb6f..f75007c0 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt @@ -30,8 +30,16 @@ import kotlin.js.Date * Input controls sizes. */ enum class InputSize(val className: String) { - LARGE("input-lg"), - SMALL("input-sm") + LARGE("form-control-lg"), + SMALL("form-control-sm") +} + +/** + * Input controls validation status. + */ +enum class ValidationStatus(val className: String) { + VALID("is-valid"), + INVALID("is-invalid") } interface FormInput : Component { @@ -47,6 +55,10 @@ interface FormInput : Component { * The name attribute of the generated HTML input element. */ var name: String? + /** + * Input control validation status. + */ + var validationStatus: ValidationStatus? /** * Makes the input element focused. @@ -78,6 +90,16 @@ interface FormControl : Component { get() = input.size set(value) { input.size = value + if (value == InputSize.SMALL) { + flabel.addCssClass("col-form-label-sm") + } else { + flabel.removeCssClass("col-form-label-sm") + } + if (value == InputSize.LARGE) { + flabel.addCssClass("col-form-label-lg") + } else { + flabel.removeCssClass("col-form-label-lg") + } } /** * The name attribute of the generated HTML input element. @@ -88,6 +110,14 @@ interface FormControl : Component { input.name = value } /** + * Input control validation status. + */ + var validationStatus: ValidationStatus? + get() = input.validationStatus + set(value) { + input.validationStatus = value + } + /** * The actual input component. */ val input: FormInput @@ -96,9 +126,9 @@ interface FormControl : Component { */ val flabel: FieldLabel /** - * Validation info component. + * Invalid feedback component. */ - val validationInfo: HelpBlock + val invalidFeedback: InvalidFeedback /** * Returns the value of the control. @@ -129,10 +159,11 @@ interface FormControl : Component { * Validator error message. */ var validatorError: String? - get() = validationInfo.content + get() = invalidFeedback.content set(value) { - validationInfo.content = value - validationInfo.visible = value != null + invalidFeedback.content = value + invalidFeedback.visible = value != null + input.validationStatus = if (value != null) ValidationStatus.INVALID else null refresh() } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt index 21281556..41e8010c 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt @@ -30,8 +30,8 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.check.CheckBox import pl.treksoft.kvision.form.check.Radio -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.form.check.RadioGroup +import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.types.KFile import kotlin.js.Date @@ -82,13 +82,14 @@ enum class FormTarget(internal val target: String) { * @param action the URL address to send data * @param enctype form encoding type * @param type form layout + * @param condensed determines if the form is condensed. * @param classes set of CSS class names * @param serializer a serializer for model type */ @Suppress("TooManyFunctions") open class FormPanel<K : Any>( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, - private val type: FormType? = null, classes: Set<String> = setOf(), + private val type: FormType? = null, condensed: Boolean = false, classes: Set<String> = setOf(), serializer: KSerializer<K> ) : SimplePanel(classes) { @@ -120,6 +121,10 @@ open class FormPanel<K : Any>( * Determines if the form should have autocomplete. */ var autocomplete: Boolean? by refreshOnUpdate() + /** + * Determines if the form is condensed. + */ + var condensed by refreshOnUpdate(condensed) /** * Function returning validation message. @@ -156,7 +161,7 @@ open class FormPanel<K : Any>( * @suppress * Internal property. */ - protected val validationAlert = Tag(TAG.H5, classes = setOf("alert", "alert-danger")).apply { + protected val validationAlert = Div(classes = setOf("alert", "alert-danger")).apply { role = "alert" visible = false } @@ -173,7 +178,9 @@ open class FormPanel<K : Any>( val cl = super.getSnClass().toMutableList() if (type != null) { cl.add(type.formType to true) + if (type == FormType.HORIZONTAL) cl.add("container-fluid" to true) } + if (condensed) cl.add("kv-form-condensed" to true) return cl } @@ -210,13 +217,28 @@ open class FormPanel<K : Any>( ): FormPanel<K> { if (type == FormType.HORIZONTAL) { if (control is CheckBox || control is Radio) { - control.addCssClass("col-sm-offset-2") + control.addCssClass("form-group") + control.addSurroundingCssClass("row") + control.addCssClass("offset-sm-2") control.addCssClass("col-sm-10") + } else if (control is RadioGroup) { + control.addCssClass("row") + control.flabel.addCssClass("col-sm-2") + control.flabel.addCssClass("col-form-label") + control.container.addCssClass("col-sm-10") + control.invalidFeedback.addCssClass("offset-sm-2") + control.invalidFeedback.addCssClass("col-sm-10") } else { + control.addCssClass("row") control.flabel.addCssClass("col-sm-2") - control.input.addSurroundingCssClass("col-sm-10") - control.validationInfo.addCssClass("col-sm-offset-2") - control.validationInfo.addCssClass("col-sm-10") + control.flabel.addCssClass("col-form-label") + control.input.addCssClass("col-sm-10") + control.invalidFeedback.addCssClass("offset-sm-2") + control.invalidFeedback.addCssClass("col-sm-10") + } + } else { + if (control is CheckBox || control is Radio) { + control.addCssClass("form-group") } } super.add(control) @@ -399,10 +421,10 @@ open class FormPanel<K : Any>( */ inline fun <reified K : Any> Container.formPanel( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, - type: FormType? = null, classes: Set<String> = setOf(), + type: FormType? = null, condensed: Boolean = false, classes: Set<String> = setOf(), noinline init: (FormPanel<K>.() -> Unit)? = null ): FormPanel<K> { - val formPanel = create<K>(method, action, enctype, type, classes) + val formPanel = create<K>(method, action, enctype, type, condensed, classes) init?.invoke(formPanel) this.add(formPanel) return formPanel @@ -411,10 +433,10 @@ open class FormPanel<K : Any>( @UseExperimental(ImplicitReflectionSerializer::class) inline fun <reified K : Any> create( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, - type: FormType? = null, classes: Set<String> = setOf(), + type: FormType? = null, condensed: Boolean = false, classes: Set<String> = setOf(), noinline init: (FormPanel<K>.() -> Unit)? = null ): FormPanel<K> { - val formPanel = FormPanel(method, action, enctype, type, classes, K::class.serializer()) + val formPanel = FormPanel(method, action, enctype, type, condensed, classes, K::class.serializer()) init?.invoke(formPanel) return formPanel } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt b/src/main/kotlin/pl/treksoft/kvision/form/HelpText.kt index 9ec3d8ae..0362d03a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/HelpText.kt @@ -25,13 +25,13 @@ import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag /** - * Helper class for Bootstrap help block element. + * Helper class for Bootstrap help text element. * * @constructor * @param content the text of the label * @param rich determines if [content] can contain HTML code */ -open class HelpBlock(content: String? = null, rich: Boolean = false) : Tag( - TAG.SPAN, content, rich, - classes = setOf("help-block", "small") +open class HelpText(content: String? = null, rich: Boolean = false) : Tag( + TAG.SMALL, content, rich, + classes = setOf("form-text", "text-muted") ) diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Label.kt b/src/main/kotlin/pl/treksoft/kvision/form/InvalidFeedback.kt index 827c90fd..dad68239 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Label.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/InvalidFeedback.kt @@ -19,33 +19,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package pl.treksoft.kvision.html +package pl.treksoft.kvision.form -import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag /** - * Simple label component rendered as *span*. + * Helper class for Bootstrap invalid feedback element. * * @constructor - * @param content label text + * @param content the text of the label * @param rich determines if [content] can contain HTML code */ -@Deprecated("Use Span class instead.") -open class Label(content: String? = null, rich: Boolean = false) : Span(content, rich) { - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - @Deprecated("User Span.Companion.span function instead.") - @Suppress("DEPRECATION") - fun Container.label( - content: String? = null, rich: Boolean = false, init: (Label.() -> Unit)? = null - ): Label { - val label = Label(content, rich).apply { init?.invoke(this) } - this.add(label) - return label - } - } -} +open class InvalidFeedback(content: String? = null, rich: Boolean = false) : Tag( + TAG.DIV, content, rich, + classes = setOf("invalid-feedback") +) diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt index 730488eb..f011b1cb 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.BoolFormControl import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -35,12 +35,11 @@ import pl.treksoft.kvision.utils.SnOn * Checkbox style options. */ enum class CheckBoxStyle(internal val className: String) { - DEFAULT("checkbox-default"), - PRIMARY("checkbox-primary"), - SUCCESS("checkbox-success"), - INFO("checkbox-info"), - WARNING("checkbox-warning"), - DANGER("checkbox-danger"), + PRIMARY("abc-checkbox-primary"), + SUCCESS("abc-checkbox-success"), + INFO("abc-checkbox-info"), + WARNING("abc-checkbox-warning"), + DANGER("abc-checkbox-danger"), } /** @@ -55,7 +54,7 @@ enum class CheckBoxStyle(internal val className: String) { open class CheckBox( value: Boolean = false, name: String? = null, label: String? = null, rich: Boolean = false -) : SimplePanel(setOf("checkbox")), BoolFormControl { +) : SimplePanel(setOf("form-check", "abc-checkbox")), BoolFormControl { /** * The selection state of the checkbox. @@ -106,22 +105,19 @@ open class CheckBox( var inline by refreshOnUpdate(false) private val idc = "kv_form_checkbox_$counter" - final override val input: CheckBoxInput = CheckBoxInput( - value, - setOf("styled") - ).apply { + final override val input: CheckBoxInput = CheckBoxInput(value, classes = setOf("form-check-input")).apply { this.id = idc this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf()) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf("form-check-label")) + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) this.addInternal(flabel) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } @@ -147,13 +143,13 @@ open class CheckBox( cl.add(it.className to true) } if (circled) { - cl.add("checkbox-circle" to true) + cl.add("abc-checkbox-circle" to true) } if (inline) { - cl.add("checkbox-inline" to true) + cl.add("form-check-inline" to true) } if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt index a486b82e..f93fd436 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt @@ -28,6 +28,7 @@ import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus /** * Type of the check input control (checkbox or radio). @@ -94,6 +95,10 @@ abstract class CheckInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() override fun render(): VNode { return render("input") @@ -101,6 +106,9 @@ abstract class CheckInput( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt index 29b3cb35..7ab509c4 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.BoolFormControl import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -35,12 +35,12 @@ import pl.treksoft.kvision.utils.SnOn * Radio style options. */ enum class RadioStyle(internal val className: String) { - DEFAULT("radio-default"), - PRIMARY("radio-primary"), - SUCCESS("radio-success"), - INFO("radio-info"), - WARNING("radio-warning"), - DANGER("radio-danger"), + DEFAULT("abc-radio-default"), + PRIMARY("abc-radio-primary"), + SUCCESS("abc-radio-success"), + INFO("abc-radio-info"), + WARNING("abc-radio-warning"), + DANGER("abc-radio-danger"), } /** @@ -56,7 +56,7 @@ enum class RadioStyle(internal val className: String) { open class Radio( value: Boolean = false, extraValue: String? = null, name: String? = null, label: String? = null, rich: Boolean = false -) : SimplePanel(), BoolFormControl { +) : SimplePanel(classes = setOf("form-check")), BoolFormControl { /** * The selection state of the radio button. @@ -115,20 +115,20 @@ open class Radio( var inline by refreshOnUpdate(false) private val idc = "kv_form_radio_$counter" - final override val input: RadioInput = RadioInput(value).apply { + final override val input: RadioInput = RadioInput(value, classes = setOf("form-check-input")).apply { this.id = idc this.extraValue = extraValue this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf()) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf("form-check-label")) + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this.eventTarget ?: this this.addInternal(input) this.addInternal(flabel) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } @@ -151,25 +151,21 @@ open class Radio( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (!squared) { - cl.add("radio" to true) + cl.add("abc-radio" to true) style?.let { cl.add(it.className to true) } - if (inline) { - cl.add("radio-inline" to true) - } } else { - cl.add("checkbox" to true) - cl.add("kv-radio-checkbox" to true) + cl.add("abc-checkbox" to true) style?.let { cl.add(it.className.replace("radio", "checkbox") to true) } - if (inline) { - cl.add("checkbox-inline" to true) - } + } + if (inline) { + cl.add("form-check-inline" to true) } if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt index 6ac58bb7..b1a0a703 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt @@ -25,9 +25,10 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.panel.SimplePanel /** @@ -97,13 +98,33 @@ open class RadioGroup( set(value) { setSizeToChildren(value) } + override var validationStatus + get() = getValidationStatusFromChildren() + set(value) { + setValidationStatusToChildren(value) + } + override var validatorError: String? + get() = super.validatorError + set(value) { + super.validatorError = value + if (value!=null) { + container.addCssClass("is-invalid") + } else { + container.removeCssClass("is-invalid") + } + } private val idc = "kv_form_radiogroup_$counter" final override val input = RadioInput() final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } + + internal val container = SimplePanel(setOf("kv-radiogroup-container")) init { + this.addInternal(flabel) + this.addInternal(container) + this.addInternal(invalidFeedback) setChildrenFromOptions() setValueToChildren(value) setNameToChildren(name) @@ -113,7 +134,7 @@ open class RadioGroup( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } if (inline) { cl.add("kv-radiogroup-inline" to true) @@ -124,7 +145,7 @@ open class RadioGroup( } private fun setValueToChildren(value: String?) { - val radios = getChildren().filterIsInstance<Radio>() + val radios = container.getChildren().filterIsInstance<Radio>() radios.forEach { it.value = false } radios.find { it.extraValue == value @@ -132,34 +153,42 @@ open class RadioGroup( } private fun getDisabledFromChildren(): Boolean { - return getChildren().filterIsInstance<Radio>().firstOrNull()?.disabled ?: false + return container.getChildren().filterIsInstance<Radio>().firstOrNull()?.disabled ?: false } private fun setDisabledToChildren(disabled: Boolean) { - getChildren().filterIsInstance<Radio>().forEach { it.disabled = disabled } + container.getChildren().filterIsInstance<Radio>().forEach { it.disabled = disabled } } private fun getNameFromChildren(): String? { - return getChildren().filterIsInstance<Radio>().firstOrNull()?.name ?: this.idc + return container.getChildren().filterIsInstance<Radio>().firstOrNull()?.name ?: this.idc } private fun setNameToChildren(name: String?) { val tname = name ?: this.idc - getChildren().filterIsInstance<Radio>().forEach { it.name = tname } + container.getChildren().filterIsInstance<Radio>().forEach { it.name = tname } } private fun getSizeFromChildren(): InputSize? { - return getChildren().filterIsInstance<Radio>().firstOrNull()?.size + return container.getChildren().filterIsInstance<Radio>().firstOrNull()?.size } private fun setSizeToChildren(size: InputSize?) { - getChildren().filterIsInstance<Radio>().forEach { it.size = size } + container.getChildren().filterIsInstance<Radio>().forEach { it.size = size } + super.size = size + } + + private fun getValidationStatusFromChildren(): ValidationStatus? { + return container.getChildren().filterIsInstance<Radio>().firstOrNull()?.validationStatus + } + + private fun setValidationStatusToChildren(validationStatus: ValidationStatus?) { + container.getChildren().filterIsInstance<Radio>().forEach { it.validationStatus = validationStatus } } private fun setChildrenFromOptions() { val currentName = this.name - super.removeAll() - this.addInternal(flabel) + container.removeAll() options?.let { val tname = currentName ?: this.idc val tinline = this.inline @@ -175,17 +204,16 @@ open class RadioGroup( } } } - super.addAll(c) + container.addAll(c) } - this.addInternal(validationInfo) } override fun focus() { - getChildren().filterIsInstance<Radio>().firstOrNull()?.focus() + container.getChildren().filterIsInstance<Radio>().firstOrNull()?.focus() } override fun blur() { - getChildren().filterIsInstance<Radio>().firstOrNull()?.blur() + container.getChildren().filterIsInstance<Radio>().firstOrNull()?.blur() } companion object { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt index fca681f6..d4301709 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroupInput.kt @@ -26,6 +26,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.panel.SimplePanel /** @@ -75,6 +76,11 @@ open class RadioGroupInput( set(value) { setSizeToChildren(value) } + override var validationStatus + get() = getValidationStatusFromChildren() + set(value) { + setValidationStatusToChildren(value) + } private val idc = "kv_form_radiogroup_$counter" @@ -128,6 +134,14 @@ open class RadioGroupInput( getChildren().filterIsInstance<Radio>().forEach { it.size = size } } + private fun getValidationStatusFromChildren(): ValidationStatus? { + return getChildren().filterIsInstance<Radio>().firstOrNull()?.validationStatus + } + + private fun setValidationStatusToChildren(validationStatus: ValidationStatus?) { + getChildren().filterIsInstance<Radio>().forEach { it.validationStatus = validationStatus } + } + private fun setChildrenFromOptions() { val currentName = this.name super.removeAll() diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt index 4d278ad2..bef14bfa 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt @@ -27,7 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -117,21 +117,21 @@ open class SimpleSelect( this.name = name } final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { @Suppress("LeakingThis") input.eventTarget = this this.addInternal(flabel) this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) counter++ } override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt index b2ba1d43..31d32052 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.panel.SimplePanel @@ -83,6 +84,10 @@ open class SimpleSelectInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() init { setChildrenFromOptions() @@ -129,6 +134,9 @@ open class SimpleSelectInput( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt index 7c23615a..091278fc 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt @@ -24,7 +24,7 @@ package pl.treksoft.kvision.form.text import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.InvalidFeedback import pl.treksoft.kvision.form.StringFormControl import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.SnOn @@ -114,7 +114,7 @@ abstract class AbstractText(label: String? = null, rich: Boolean = false) : protected val idc = "kv_form_text_$counter" abstract override val input: AbstractTextInput final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { this.addInternal(flabel) @@ -128,7 +128,7 @@ abstract class AbstractText(label: String? = null, rich: Boolean = false) : override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (validatorError != null) { - cl.add("has-error" to true) + cl.add("text-danger" to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt index e7ecba8a..192b33c8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize +import pl.treksoft.kvision.form.ValidationStatus /** * Base class for basic text components. @@ -87,9 +88,16 @@ abstract class AbstractTextInput( * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** + * The validation status of the input. + */ + override var validationStatus: ValidationStatus? by refreshOnUpdate() override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() + validationStatus?.let { + cl.add(it.className to true) + } size?.let { cl.add(it.className to true) } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt index 7e4127f5..f493b06e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt @@ -64,7 +64,7 @@ open class Text( @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) } companion object { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt index d5058583..ccf17892 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt @@ -73,7 +73,7 @@ open class TextArea( @Suppress("LeakingThis") input.eventTarget = this this.addInternal(input) - this.addInternal(validationInfo) + this.addInternal(invalidFeedback) } companion object { diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt index 0b6b43e5..aaa0f735 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt @@ -33,13 +33,23 @@ import pl.treksoft.kvision.core.Widget * Button styles. */ enum class ButtonStyle(val className: String) { - DEFAULT("btn-default"), PRIMARY("btn-primary"), + SECONDARY("btn-secondary"), SUCCESS("btn-success"), - INFO("btn-info"), - WARNING("btn-warning"), DANGER("btn-danger"), - LINK("btn-link") + WARNING("btn-warning"), + INFO("btn-info"), + LIGHT("btn-light"), + DARK("btn-dark"), + LINK("btn-link"), + OUTLINEPRIMARY("btn-outline-primary"), + OUTLINESECONDARY("btn-outline-secondary"), + OUTLINESUCCESS("btn-outline-success"), + OUTLINEDANGER("btn-outline-danger"), + OUTLINEWARNING("btn-outline-warning"), + OUTLINEINFO("btn-outline-info"), + OUTLINELIGHT("btn-outline-light"), + OUTLINEDARK("btn-outline-dark") } /** @@ -47,8 +57,7 @@ enum class ButtonStyle(val className: String) { */ enum class ButtonSize(internal val className: String) { LARGE("btn-lg"), - SMALL("btn-sm"), - XSMALL("btn-xs") + SMALL("btn-sm") } /** @@ -71,7 +80,7 @@ enum class ButtonType(internal val buttonType: String) { * @param classes a set of CSS class names */ open class Button( - text: String, icon: String? = null, style: ButtonStyle = ButtonStyle.DEFAULT, type: ButtonType = ButtonType.BUTTON, + text: String, icon: String? = null, style: ButtonStyle = ButtonStyle.PRIMARY, type: ButtonType = ButtonType.BUTTON, disabled: Boolean = false, classes: Set<String> = setOf() ) : Widget(classes) { @@ -123,14 +132,16 @@ open class Button( if (block) { cl.add("btn-block" to true) } - if (disabled) { - cl.add("disabled" to true) - } return cl } override fun getSnAttrs(): List<StringPair> { - return super.getSnAttrs() + ("type" to type.buttonType) + val snattrs = super.getSnAttrs().toMutableList() + snattrs.add("type" to type.buttonType) + if (disabled) { + snattrs.add("disabled" to "disabled") + } + return snattrs } /** @@ -154,7 +165,7 @@ open class Button( fun Container.button( text: String, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, + style: ButtonStyle = ButtonStyle.PRIMARY, type: ButtonType = ButtonType.BUTTON, disabled: Boolean = false, classes: Set<String> = setOf(), diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt b/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt index 7e10c10f..a9fb03db 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Icon.kt @@ -39,13 +39,7 @@ open class Icon(icon: String) : Tag(TAG.SPAN) { override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() - if (icon.startsWith("fa-")) { - cl.add("fa" to true) - cl.add(icon to true) - } else { - cl.add("glyphicon" to true) - cl.add("glyphicon-$icon" to true) - } + icon.split(" ").forEach { cl.add(it to true) } return cl } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt index 4d373270..81873088 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt @@ -32,8 +32,8 @@ import pl.treksoft.kvision.core.Widget * Image shapes. */ enum class ImageShape(internal val className: String) { - ROUNDED("img-rounded"), - CIRCLE("img-circle"), + ROUNDED("rounded"), + CIRCLE("rounded-circle"), THUMBNAIL("img-thumbnail") } @@ -89,7 +89,7 @@ open class Image( override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (responsive) { - cl.add("img-responsive" to true) + cl.add("img-fluid" to true) } if (centered) { cl.add("center-block" to true) diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt index 5fc613e2..63104248 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt @@ -26,7 +26,6 @@ import org.w3c.dom.events.MouseEvent import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.dropdown.DropDown import pl.treksoft.kvision.panel.SimplePanel /** @@ -99,37 +98,5 @@ open class Link( this.add(link) return link } - - /** - * DSL builder extension function for a disabled link in a dropdown list. - * - * It takes the same parameters as the constructor of the built component. - */ - fun ListTag.linkDisabled( - label: String, icon: String? = null, image: ResString? = null, - classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null - ): Link { - val link = Link(label, null, icon, image, classes).apply { init?.invoke(this) } - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(link) - this.add(tag) - return link - } - - /** - * DSL builder extension function for a disabled link in a dropdown list. - * - * It takes the same parameters as the constructor of the built component. - */ - fun DropDown.linkDisabled( - label: String, icon: String? = null, image: ResString? = null, - classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null - ): Link { - val link = Link(label, "javascript:void(0)", icon, image, classes).apply { init?.invoke(this) } - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(link) - this.add(tag) - return link - } } } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/List.kt b/src/main/kotlin/pl/treksoft/kvision/html/List.kt index 5fb489da..cf3f8be6 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/List.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/List.kt @@ -27,7 +27,6 @@ import pl.treksoft.kvision.KVManager import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.dropdown.DropDown import pl.treksoft.kvision.panel.SimplePanel /** @@ -98,14 +97,14 @@ open class ListTag( val childrenElements = children.filter { it.visible } val res = when (type) { ListType.UL, ListType.OL, ListType.UNSTYLED, ListType.INLINE -> childrenElements.map { v -> - if (v is Tag && v.type == TAG.LI || v is DropDown && v.forNavbar) { + if (v is Tag && v.type == TAG.LI /*|| v is DropDown && v.forNavbar*/) { v.renderVNode() } else { h("li", arrayOf(v.renderVNode())) } } ListType.DL, ListType.DL_HORIZ -> childrenElements.mapIndexed { index, v -> - if (v is Tag && v.type == TAG.LI || v is DropDown && v.forNavbar) { + if (v is Tag && v.type == TAG.LI /*|| v is DropDown && v.forNavbar*/) { v.renderVNode() } else { h(if (index % 2 == 0) "dt" else "dd", arrayOf(v.renderVNode())) diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt index 512ca8b8..a5e855ae 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt @@ -73,6 +73,12 @@ enum class TAG(internal val tagName: String) { BR("br"), CAPTION("caption"), + FIGURE("figure"), + FIGCAPTION("figcaption"), + PICTURE("figcaption"), + SOURCE("figcaption"), + + TABLE("table"), THEAD("thead"), TH("th"), TBODY("tbody"), diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt index 2d9dcc46..e0c70ac4 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt @@ -27,8 +27,7 @@ import org.w3c.dom.HTMLElement import pl.treksoft.kvision.KVManager import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.Style -import pl.treksoft.kvision.dropdown.ContextMenu -import pl.treksoft.kvision.modal.Modal +import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.utils.snClasses import pl.treksoft.kvision.utils.snOpt @@ -52,7 +51,7 @@ class Root( private val fixed: Boolean = false, init: (Root.() -> Unit)? = null ) : SimplePanel() { - private val contextMenus: MutableList<ContextMenu> = mutableListOf() + private val contextMenus: MutableList<Widget> = mutableListOf() private var rootVnode: VNode = renderVNode() internal var renderDisabled = false @@ -71,7 +70,7 @@ class Root( } roots.add(this) if (isFirstRoot) { - Modal.modals.forEach { it.parent = this } + modals.forEach { it.parent = this } } @Suppress("LeakingThis") init?.invoke(this) @@ -87,7 +86,7 @@ class Root( } } - internal fun addContextMenu(contextMenu: ContextMenu) { + fun addContextMenu(contextMenu: Widget) { contextMenus.add(contextMenu) contextMenu.parent = this this.setInternalEventListener<Root> { @@ -114,7 +113,7 @@ class Root( private fun modalsVNodes(): Array<VNode> { return if (isFirstRoot) { - Modal.modals.filter { it.visible }.map { it.renderVNode() }.toTypedArray() + modals.filter { it.visible }.map { it.renderVNode() }.toTypedArray() } else { arrayOf() } @@ -150,12 +149,13 @@ class Root( roots.remove(this) if (isFirstRoot) { Style.styles.clear() - Modal.modals.clear() + modals.clear() } } companion object { internal var counter = 0 + private val modals: MutableList<Widget> = mutableListOf() /** * @suppress internal function @@ -167,18 +167,26 @@ class Root( internal val roots: MutableList<Root> = mutableListOf() - internal fun getFirstRoot(): Root? { + fun getFirstRoot(): Root? { return if (roots.isNotEmpty()) roots[0] else null } - internal fun getLastRoot(): Root? { + fun getLastRoot(): Root? { return if (roots.isNotEmpty()) roots[roots.size - 1] else null } + + fun addModal(modal: Widget) { + modals.add(modal) + } + + fun removeModal(modal: Widget) { + modals.remove(modal) + } } } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt index 2f702fad..91eeda80 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt @@ -35,7 +35,7 @@ import pl.treksoft.kvision.core.Widget */ open class SimplePanel(classes: Set<String> = setOf(), init: (SimplePanel.() -> Unit)? = null) : Widget(classes), Container { - internal val children: MutableList<Component> = mutableListOf() + protected val children: MutableList<Component> = mutableListOf() init { @Suppress("LeakingThis") @@ -94,7 +94,7 @@ open class SimplePanel(classes: Set<String> = setOf(), init: (SimplePanel.() -> } override fun getChildren(): List<Component> { - return ArrayList(children) + return children } override fun dispose() { diff --git a/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt b/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt index 0a79c9f9..44646897 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt @@ -64,6 +64,22 @@ open class Cell( this.add(cell) return cell } + + /** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ + fun Row.thcell( + content: String? = null, + rich: Boolean = false, + align: Align? = null, + classes: Set<String> = setOf(), init: (HeaderCell.() -> Unit)? = null + ): HeaderCell { + val headerCell = HeaderCell(content, rich, align, Scope.ROW, classes, init) + this.add(headerCell) + return headerCell + } } } diff --git a/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt b/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt index b70845d6..14527f0f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt @@ -25,6 +25,11 @@ import pl.treksoft.kvision.html.Align import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +enum class Scope(internal val scope: String) { + ROW("row"), + COL("col") +} + /** * HTML table header cell component. * @@ -39,11 +44,16 @@ open class HeaderCell( content: String? = null, rich: Boolean = false, align: Align? = null, + scope: Scope? = null, classes: Set<String> = setOf(), init: (HeaderCell.() -> Unit)? = null ) : Tag(TAG.TH, content, rich, align, classes) { init { + scope?.let { + @Suppress("LeakingThis") + setAttribute("scope", it.scope) + } @Suppress("LeakingThis") init?.invoke(this) } @@ -58,9 +68,10 @@ open class HeaderCell( content: String? = null, rich: Boolean = false, align: Align? = null, + scope: Scope? = null, classes: Set<String> = setOf(), init: (HeaderCell.() -> Unit)? = null ): HeaderCell { - val cell = HeaderCell(content, rich, align, classes, init) + val cell = HeaderCell(content, rich, align, scope, classes, init) this.add(cell) return cell } diff --git a/src/main/kotlin/pl/treksoft/kvision/table/Table.kt b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt index 11ed52fc..6d7c9b6e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/Table.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt @@ -38,8 +38,29 @@ import pl.treksoft.kvision.utils.snOpt enum class TableType(val type: String) { STRIPED("table-striped"), BORDERED("table-bordered"), + BORDERLESS("table-borderless"), HOVER("table-hover"), - CONDENSED("table-condensed") + SMALL("table-sm"), + DARK("table-dark") +} + +/** + * HTML table responsive types. + */ +enum class ResponsiveType(val type: String) { + RESPONSIVE("table-responsive"), + RESPONSIVESM("table-responsive-sm"), + RESPONSIVEMD("table-responsive-md"), + RESPONSIVELG("table-responsive-lg"), + RESPONSIVEXL("table-responsive-xl") +} + +/** + * HTML table header types. + */ +enum class TheadType(internal val type: String) { + DARK("thead-dark"), + LIGHT("thead-light") } /** @@ -56,8 +77,8 @@ enum class TableType(val type: String) { @Suppress("TooManyFunctions") open class Table( headerNames: List<String>? = null, - types: Set<TableType> = setOf(), caption: String? = null, responsive: Boolean = false, - classes: Set<String> = setOf(), init: (Table.() -> Unit)? = null + types: Set<TableType> = setOf(), caption: String? = null, responsiveType: ResponsiveType? = null, + theadType: TheadType? = null, classes: Set<String> = setOf(), init: (Table.() -> Unit)? = null ) : SimplePanel(classes + "table") { /** @@ -75,10 +96,13 @@ open class Table( /** * Determines if the table is responsive. */ - var responsive by refreshOnUpdate(responsive) + var responsiveType by refreshOnUpdate(responsiveType) private val theadRow = Tag(TAG.TR) - private val thead = Tag(TAG.THEAD).add(theadRow) + private val thead = Tag(TAG.THEAD).apply { + if (theadType != null) addCssClass(theadType.type) + add(theadRow) + } private val tbody = Tag(TAG.TBODY) init { @@ -94,7 +118,7 @@ open class Table( private fun refreshHeaders() { theadRow.removeAll() headerNames?.forEach { - theadRow.add(HeaderCell(it)) + theadRow.add(HeaderCell(it, scope = Scope.COL)) } } @@ -128,9 +152,9 @@ open class Table( } override fun render(): VNode { - return if (responsive) { + return if (responsiveType != null) { val opt = snOpt { - `class` = snClasses(listOf("table-responsive" to true)) + `class` = snClasses(listOf(responsiveType!!.type to true)) } h("div", opt, arrayOf(render("table", childrenVNodes()))) } else { @@ -185,11 +209,11 @@ open class Table( */ fun Container.table( headerNames: List<String>? = null, - types: Set<TableType> = setOf(), caption: String? = null, responsive: Boolean = false, - classes: Set<String> = setOf(), init: (Table.() -> Unit)? = null + types: Set<TableType> = setOf(), caption: String? = null, responsiveType: ResponsiveType? = null, + theadType: TheadType? = null, classes: Set<String> = setOf(), init: (Table.() -> Unit)? = null ): Table { val table = - Table(headerNames, types, caption, responsive, classes, init) + Table(headerNames, types, caption, responsiveType, theadType, classes, init) this.add(table) return table } diff --git a/src/main/resources/css/style.css b/src/main/resources/css/style.css new file mode 100644 index 00000000..7323772b --- /dev/null +++ b/src/main/resources/css/style.css @@ -0,0 +1,78 @@ +.splitpanel-vertical { + display: flex; + flex-direction: row; + overflow: auto; +} + +.splitpanel-vertical > *:first-child { + max-width: calc(100% - 9px); +} + +.splitpanel-vertical > * { + flex: 0 0 auto; + overflow: auto; +} + +.splitpanel-vertical > *:last-child { + flex: 1 1 auto; + overflow: auto; +} + +.splitpanel-horizontal { + display: flex; + flex-direction: column; + overflow: auto; +} + +.splitpanel-horizontal > *:first-child { + max-height: calc(100% - 9px); +} + +.splitpanel-horizontal > * { + flex: 0 0 auto; + overflow: auto; +} + +.splitpanel-horizontal > *:last-child { + flex: 1 1 auto; + overflow: auto; +} + + +.splitter-vertical { + flex: 0 0 auto; + width: 9px; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAhCAQAAABOpSL+AAAAIklEQVR4AWMwbb/PdR+JZDD9f1/oPhI5sgVGBSruc9xHIgGdSQqqQJGkRgAAAABJRU5ErkJggg==') center center no-repeat #cecece; + cursor: col-resize; +} + +.splitter-horizontal { + flex: 0 0 auto; + height: 9px; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAICAQAAADdTl4aAAAAIElEQVQoz2MwrTD9TxFsZ7jPcV+IIsjFQAUw6hFqegQA+xzRHT2p7pEAAAAASUVORK5CYII=') center center no-repeat #cecece; + cursor: row-resize; +} + +.trix-control { + overflow-y: auto; +} + +trix-toolbar .trix-button-group { + margin-bottom: 3px; +} + +.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select { + border: 1px solid #ccc; + border-radius: 4px; +} + +.tabulator-row .tabulator-cell.tabulator-editing input:focus, .tabulator-row .tabulator-cell.tabulator-editing select:focus { + border-color: #66afe9; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6); +} + +.tabulator-row .tabulator-cell.tabulator-editing { + border-right: 1px solid #1d68cd !important; + padding: 2px !important; +} diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/HelpBlockSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/HelpTextSpec.kt index c7c4ede5..4be84d22 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/HelpBlockSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/HelpTextSpec.kt @@ -21,7 +21,7 @@ */ package test.pl.treksoft.kvision.form -import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.HelpText import pl.treksoft.kvision.panel.Root import test.pl.treksoft.kvision.DomSpec import kotlin.browser.document @@ -33,7 +33,7 @@ class HelpBlockSpec : DomSpec { fun render() { run { val root = Root("test", fixed = true) - val fl = HelpBlock("Form Error") + val fl = HelpText("Form Error") root.add(fl) val element = document.getElementById("test") assertEqualsHtml( diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt index a8fbbcc5..bd0b3993 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/check/RadioSpec.kt @@ -52,7 +52,7 @@ class RadioSpec : DomSpec { ci.squared = true ci.inline = false assertEqualsHtml( - "<div class=\"checkbox kv-radio-checkbox checkbox-info\"><input id=\"$id\" type=\"radio\" checked=\"checked\" name=\"name\" disabled=\"disabled\" value=\"abc\"><label for=\"$id\">Label</label></div>", + "<div class=\"checkbox checkbox-info\"><input id=\"$id\" type=\"radio\" checked=\"checked\" name=\"name\" disabled=\"disabled\" value=\"abc\"><label for=\"$id\">Label</label></div>", element?.innerHTML, "Should render correct radio button form control" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt index 7ce811fa..2bc35a38 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/text/TextSpec.kt @@ -49,7 +49,7 @@ class TextSpec : DomSpec { ) ti.validatorError = "Validation Error" assertEqualsHtml( - "<div class=\"form-group has-error\"><label class=\"control-label\" for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" placeholder=\"place\" name=\"name\" maxlength=\"15\" disabled=\"disabled\" type=\"text\" value=\"abc\"><span class=\"help-block small\">Validation Error</span></div>", + "<div class=\"form-group text-danger\"><label class=\"control-label\" for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" placeholder=\"place\" name=\"name\" maxlength=\"15\" disabled=\"disabled\" type=\"text\" value=\"abc\"><span class=\"help-block small\">Validation Error</span></div>", element?.innerHTML, "Should render correct input form control with validation error" ) diff --git a/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt index 997da597..c312040a 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/table/TableSpec.kt @@ -23,6 +23,7 @@ package test.pl.treksoft.kvision.table import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.table.Cell.Companion.cell +import pl.treksoft.kvision.table.ResponsiveType import pl.treksoft.kvision.table.Row.Companion.row import pl.treksoft.kvision.table.Table import pl.treksoft.kvision.table.TableType @@ -50,7 +51,7 @@ class TableSpec : DomSpec { "Should render correct table" ) table.caption = "Caption" - table.responsive = true + table.responsiveType = ResponsiveType.RESPONSIVE table.types = setOf(TableType.BORDERED) val element2 = document.getElementById("test") assertEqualsHtml( |