aboutsummaryrefslogtreecommitdiff
path: root/kvision-modules
diff options
context:
space:
mode:
Diffstat (limited to 'kvision-modules')
-rw-r--r--kvision-modules/kvision-bootstrap-css/build.gradle5
-rw-r--r--kvision-modules/kvision-bootstrap-css/package.json.d/project.info3
-rw-r--r--kvision-modules/kvision-bootstrap-css/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrapCss.kt35
-rw-r--r--kvision-modules/kvision-bootstrap-css/src/main/resources/css/paper.css (renamed from kvision-modules/kvision-bootstrap/src/main/resources/css/paper.css)0
-rw-r--r--kvision-modules/kvision-bootstrap-css/webpack.config.d/bootstrap.js4
-rw-r--r--kvision-modules/kvision-bootstrap-css/webpack.config.d/css.js (renamed from kvision-modules/kvision-datetime/webpack.config.d/css.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-css/webpack.config.d/jquery.js (renamed from kvision-modules/kvision-spinner/webpack.config.d/jquery.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/build.gradle (renamed from kvision-modules/kvision-datetime/build.gradle)4
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/package.json.d/project.info (renamed from kvision-modules/kvision-datetime/package.json.d/project.info)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt (renamed from kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/KVManagerDatetime.kt)10
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt (renamed from kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt)8
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt (renamed from kvision-modules/kvision-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt)8
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ka.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ms.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nb.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt-BR.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs-latin.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sw.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh-TW.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js (renamed from kvision-modules/kvision-datetime/src/main/resources/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt (renamed from kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt (renamed from kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt (renamed from kvision-modules/kvision-datetime/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt)2
-rw-r--r--kvision-modules/kvision-bootstrap-datetime/webpack.config.d/css.js (renamed from kvision-modules/kvision-select/webpack.config.d/css.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-dialog/build.gradle (renamed from kvision-modules/kvision-dialog/build.gradle)1
-rw-r--r--kvision-modules/kvision-bootstrap-dialog/package.json.d/project.info (renamed from kvision-modules/kvision-dialog/package.json.d/project.info)0
-rw-r--r--kvision-modules/kvision-bootstrap-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt (renamed from kvision-modules/kvision-dialog/src/main/kotlin/pl/treksoft/kvision/modal/Dialog.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-select-remote/build.gradle (renamed from kvision-modules/kvision-select-remote/build.gradle)2
-rw-r--r--kvision-modules/kvision-bootstrap-select-remote/package.json.d/project.info (renamed from kvision-modules/kvision-select-remote/package.json.d/project.info)0
-rw-r--r--kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt (renamed from kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt)8
-rw-r--r--kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt (renamed from kvision-modules/kvision-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/build.gradle (renamed from kvision-modules/kvision-select/build.gradle)4
-rw-r--r--kvision-modules/kvision-bootstrap-select/package.json.d/project.info (renamed from kvision-modules/kvision-select/package.json.d/project.info)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt (renamed from kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/KVManagerSelect.kt)16
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt (renamed from kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt (renamed from kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt)8
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt (renamed from kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt)8
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt (renamed from kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt (renamed from kvision-modules/kvision-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt)6
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.en-US.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js (renamed from kvision-modules/kvision-select/src/main/resources/js/locales/bootstrap-select/bootstrap-select-i18n.min.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt (renamed from kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt (renamed from kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectInputSpec.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt (renamed from kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptGroupSpec.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt (renamed from kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectOptionSpec.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt (renamed from kvision-modules/kvision-select/src/test/kotlin/test/pl/treksoft/kvision/form/select/SelectSpec.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-select/webpack.config.d/css.js (renamed from kvision-modules/kvision-spinner/webpack.config.d/css.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-spinner/build.gradle (renamed from kvision-modules/kvision-spinner/build.gradle)4
-rw-r--r--kvision-modules/kvision-bootstrap-spinner/package.json.d/project.info (renamed from kvision-modules/kvision-spinner/package.json.d/project.info)0
-rw-r--r--kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt (renamed from kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/KVManagerSpinner.kt)10
-rw-r--r--kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt (renamed from kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt)8
-rw-r--r--kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt (renamed from kvision-modules/kvision-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt)12
-rw-r--r--kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt (renamed from kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt (renamed from kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt (renamed from kvision-modules/kvision-spinner/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt)2
-rw-r--r--kvision-modules/kvision-bootstrap-spinner/webpack.config.d/css.js (renamed from kvision-modules/kvision-upload/webpack.config.d/css.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-spinner/webpack.config.d/jquery.js5
-rw-r--r--kvision-modules/kvision-bootstrap-upload/build.gradle (renamed from kvision-modules/kvision-upload/build.gradle)1
-rw-r--r--kvision-modules/kvision-bootstrap-upload/package.json.d/project.info (renamed from kvision-modules/kvision-upload/package.json.d/project.info)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt (renamed from kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/KVManagerUpload.kt)15
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt (renamed from kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt)8
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt (renamed from kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt)8
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt (renamed from kvision-modules/kvision-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ar.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/az.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/bg.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ca.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cr.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/cs.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/da.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/de.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/el.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/es.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/et.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fa.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fi.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/fr.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/gl.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/he.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/hu.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/id.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/it.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ja.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ka.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ko.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/kz.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/lt.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/nl.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/no.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pl.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt-BR.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/pt.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ro.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/ru.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sk.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sl.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/sv.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/th.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/tr.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uk.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/uz.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/vi.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh-TW.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js (renamed from kvision-modules/kvision-upload/src/main/resources/js/locales/bootstrap-fileinput/zh.js)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt (renamed from kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/TestUtil.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt (renamed from kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadInputSpec.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt (renamed from kvision-modules/kvision-upload/src/test/kotlin/test/pl/treksoft/kvision/form/upload/UploadSpec.kt)0
-rw-r--r--kvision-modules/kvision-bootstrap-upload/webpack.config.d/css.js2
-rw-r--r--kvision-modules/kvision-bootstrap-upload/webpack.config.d/file.js (renamed from kvision-modules/kvision-upload/webpack.config.d/file.js)0
-rw-r--r--kvision-modules/kvision-bootstrap/build.gradle5
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/KVManagerBootstrap.kt55
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/core/Component.kt133
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt112
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt417
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt61
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt57
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt121
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt48
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt176
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt292
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt110
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt72
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt229
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt185
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt273
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt162
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt125
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt109
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt63
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt48
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt48
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt449
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/resources/css/kvbootstrap.css291
-rw-r--r--kvision-modules/kvision-bootstrap/src/main/resources/css/style.css226
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt75
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt46
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt46
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt54
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt54
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt70
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt50
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt117
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt56
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt55
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt57
-rw-r--r--kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt47
-rw-r--r--kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/KVManagerChart.kt6
-rw-r--r--kvision-modules/kvision-fontawesome/build.gradle9
-rw-r--r--kvision-modules/kvision-fontawesome/package.json.d/project.info3
-rw-r--r--kvision-modules/kvision-fontawesome/src/main/kotlin/pl/treksoft/kvision/KVManagerFontAwesome.kt35
-rw-r--r--kvision-modules/kvision-fontawesome/webpack.config.d/bootstrap.js4
-rw-r--r--kvision-modules/kvision-fontawesome/webpack.config.d/css.js2
-rw-r--r--kvision-modules/kvision-fontawesome/webpack.config.d/jquery.js5
-rw-r--r--kvision-modules/kvision-handlebars/src/main/kotlin/pl/treksoft/kvision/KVManagerHandlebars.kt6
-rw-r--r--kvision-modules/kvision-i18n/src/main/kotlin/pl/treksoft/kvision/KVManagerI18n.kt6
-rw-r--r--kvision-modules/kvision-moment/src/main/kotlin/pl/treksoft/kvision/KVManagerMoment.kt8
-rw-r--r--kvision-modules/kvision-pace/src/main/kotlin/pl/treksoft/kvision/KVManagerPace.kt8
-rw-r--r--kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/KVManagerRedux.kt14
-rw-r--r--kvision-modules/kvision-remote/src/main/kotlin/pl/treksoft/kvision/remote/Profile.kt8
-rw-r--r--kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/KVManagerRichText.kt10
-rw-r--r--kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt2
-rw-r--r--kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/KVManagerTabulator.kt14
211 files changed, 4557 insertions, 384 deletions
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/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt
new file mode 100644
index 00000000..4e20de81
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt
@@ -0,0 +1,112 @@
+/*
+ * 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.dropdown
+
+import org.w3c.dom.events.MouseEvent
+import pl.treksoft.kvision.core.Display
+import pl.treksoft.kvision.core.Widget
+import pl.treksoft.kvision.html.Div
+import pl.treksoft.kvision.panel.Root
+import pl.treksoft.kvision.utils.px
+
+/**
+ * Context menu component.
+ *
+ * @constructor
+ * @param element an element to bind
+ * @param fixedPosition use fixed positioning
+ * @param classes a set of CSS class names
+ */
+open class ContextMenu(
+ element: Widget? = null,
+ protected val fixedPosition: Boolean = false,
+ classes: Set<String> = setOf(), init: (ContextMenu.() -> Unit)? = null
+) : Div(classes = classes + "dropdown-menu") {
+
+ init {
+ @Suppress("LeakingThis")
+ hide()
+ @Suppress("LeakingThis")
+ display = Display.BLOCK
+ val root = element?.getRoot() ?: Root.getLastRoot()
+ if (root != null) {
+ @Suppress("LeakingThis")
+ root.addContextMenu(this)
+ } else {
+ println("At least one Root object is required to create a context menu!")
+ }
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ /**
+ * Positions and shows a context menu based on a mouse event.
+ * @param mouseEvent mouse event
+ * @return current context menu
+ */
+ open fun positionMenu(mouseEvent: MouseEvent): ContextMenu {
+ if (fixedPosition) {
+ this.top = DEFAULT_FIXED_POS_Y.px
+ this.left = DEFAULT_FIXED_POS_X.px
+ } else {
+ this.top = mouseEvent.pageY.toInt().px
+ this.left = mouseEvent.pageX.toInt().px
+ }
+ this.show()
+ return this
+ }
+
+ companion object {
+
+ const val DEFAULT_FIXED_POS_X = 5
+ 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.
+ */
+ fun Widget.contextMenu(
+ fixedPosition: Boolean = false,
+ classes: Set<String> = setOf(), init: (ContextMenu.() -> Unit)? = null
+ ): ContextMenu {
+ val contextMenu = ContextMenu(this, fixedPosition, classes).apply { init?.invoke(this) }
+ this.setContextMenu(contextMenu)
+ return contextMenu
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt
new file mode 100644
index 00000000..9862b322
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt
@@ -0,0 +1,417 @@
+/*
+ * 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.dropdown
+
+import com.github.snabbdom.VNode
+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.panel.SimplePanel
+import pl.treksoft.kvision.utils.obj
+
+/**
+ * Useful options for use in DropDown's *elements* parameter.
+ */
+enum class DD(val option: String) {
+ HEADER("DD#HEADER"),
+ DISABLED("DD#DISABLED"),
+ SEPARATOR("DD#SEPARATOR")
+}
+
+/**
+ * Dropdown directions.
+ */
+enum class Direction(internal val direction: String) {
+ DROPDOWN("dropdown"),
+ DROPUP("dropup"),
+ DROPLEFT("dropleft"),
+ DROPRIGHT("dropright")
+}
+
+/**
+ * Bootstrap dropdown component.
+ *
+ * @constructor
+ * @param text the label of the dropdown button
+ * @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 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.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.
+ */
+ var text
+ get() = button.text
+ set(value) {
+ button.text = value
+ }
+ private var elements by refreshOnUpdate(elements) { setChildrenFromElements() }
+ /**
+ * The icon of the dropdown button.
+ */
+ var icon
+ get() = button.icon
+ set(value) {
+ button.icon = value
+ }
+ /**
+ * The style of the dropdown button.
+ */
+ var style
+ get() = button.style
+ set(value) {
+ button.style = value
+ }
+ /**
+ * The size of the dropdown button.
+ */
+ var size
+ get() = button.size
+ set(value) {
+ button.size = value
+ }
+ /**
+ * Determines if the dropdown button takes all the space horizontally.
+ */
+ var block
+ get() = button.block
+ set(value) {
+ button.block = value
+ }
+ /**
+ * Determines if the dropdown is disabled.
+ */
+ var disabled
+ get() = button.disabled
+ set(value) {
+ button.disabled = value
+ }
+ /**
+ * The image on the dropdown button.
+ */
+ var image
+ get() = button.image
+ set(value) {
+ button.image = value
+ }
+ /**
+ * The direction of the dropdown.
+ */
+ var direction by refreshOnUpdate(direction)
+ /**
+ * Width of the dropdown button.
+ */
+ override var width: CssSize?
+ get() = super.width
+ set(value) {
+ super.width = value
+ button.width = value
+ }
+
+ private val idc = "kv_dropdown_$counter"
+ internal val button: DropDownButton = DropDownButton(
+ idc, text, icon, style, disabled, forNavbar, forDropDown
+ )
+
+ fun buttonId() = button.id
+
+ internal val list: DropDownDiv = DropDownDiv(idc)
+
+ init {
+ if (forDropDown) {
+ this.style = ButtonStyle.LIGHT
+ this.direction = Direction.DROPRIGHT
+ }
+ setChildrenFromElements()
+ this.addInternal(button)
+ this.addInternal(list)
+ counter++
+ }
+
+ override fun render(): VNode {
+ return if (forNavbar) {
+ render("li", childrenVNodes())
+ } else {
+ render("div", childrenVNodes())
+ }
+ }
+
+ override fun add(child: Component): SimplePanel {
+ list.add(child)
+ return this
+ }
+
+ override fun addAll(children: List<Component>): SimplePanel {
+ list.addAll(children)
+ return this
+ }
+
+ override fun remove(child: Component): SimplePanel {
+ list.remove(child)
+ return this
+ }
+
+ override fun removeAll(): SimplePanel {
+ list.removeAll()
+ return this
+ }
+
+ override fun getChildren(): List<Component> {
+ return list.getChildren()
+ }
+
+ private fun setChildrenFromElements() {
+ list.removeAll()
+ elements?.let { elems ->
+ val c = elems.map {
+ when (it.second) {
+ DD.HEADER.option -> Header(it.first)
+ DD.SEPARATOR.option -> Separator()
+ DD.DISABLED.option -> {
+ Link(it.first, "javascript:void(0)", classes = setOf("dropdown-item", "disabled")).apply {
+ tabindex = -1
+ setAttribute("aria-disabled", "true")
+ }
+ }
+ else -> Link(it.first, it.second, classes = setOf("dropdown-item"))
+ }
+ }
+ list.addAll(c)
+ }
+ }
+
+ @Suppress("UnsafeCastFromDynamic")
+ override fun afterInsert(node: VNode) {
+ this.getElementJQuery()?.on("show.bs.dropdown") { e, _ ->
+ this.dispatchEvent("showBsDropdown", obj { detail = e })
+ }
+ this.getElementJQuery()?.on("shown.bs.dropdown") { e, _ ->
+ this.dispatchEvent("shownBsDropdown", obj { detail = e })
+ }
+ this.getElementJQuery()?.on("hide.bs.dropdown") { e, _ ->
+ this.dispatchEvent("hideBsDropdown", obj { detail = e })
+ }
+ this.getElementJQuery()?.on("hidden.bs.dropdown") { e, _ ->
+ this.dispatchEvent("hiddenBsDropdown", obj { detail = e })
+ }
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ if (forNavbar) cl.add("nav-item" to true)
+ cl.add(direction.direction to true)
+ return cl
+ }
+
+ /**
+ * Toggles dropdown visibility.
+ */
+ open fun toggle() {
+ this.button.getElementJQuery()?.click()
+ }
+
+ companion object {
+ internal var counter = 0
+
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Container.dropDown(
+ text: String, elements: List<StringPair>? = null, icon: String? = 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(
+ text,
+ elements,
+ icon,
+ style,
+ direction,
+ disabled,
+ forNavbar,
+ 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
+ }
+
+ }
+}
+
+internal class DropDownButton(
+ id: String,
+ text: String,
+ icon: String? = null,
+ style: ButtonStyle = ButtonStyle.PRIMARY,
+ disabled: Boolean = false,
+ val forNavbar: Boolean = false,
+ val forDropDown: Boolean = false,
+ classes: Set<String> = setOf()
+) :
+ Button(text, icon, style, ButtonType.BUTTON, disabled, classes) {
+
+ init {
+ this.id = id
+ if (!forNavbar && !forDropDown) this.role = "button"
+ setInternalEventListener<DropDownButton> {
+ click = { e ->
+ 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 || forDropDown) {
+ render("a", text)
+ } else {
+ render("button", text)
+ }
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ return if (forNavbar) {
+ 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() + ("dropdown-toggle" to true)
+ }
+ }
+
+ override fun getSnAttrs(): List<StringPair> {
+ 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 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/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt
new file mode 100644
index 00000000..13e0b2e4
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.dropdown
+
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+
+/**
+ * Menu header component.
+ *
+ * @constructor
+ * @param content header content text
+ * @param classes a set of CSS class names
+ */
+open class Header(content: String? = null, classes: Set<String> = setOf()) :
+ Tag(TAG.H6, content, classes = classes + "dropdown-header") {
+
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun ContextMenu.header(content: String? = null, classes: Set<String> = setOf()): Header {
+ val header = Header(content, classes)
+ this.add(header)
+ return header
+ }
+
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun DropDown.header(content: String? = null, classes: Set<String> = setOf()): Header {
+ val header = Header(content, classes)
+ this.add(header)
+ return header
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt
new file mode 100644
index 00000000..dd2344bd
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.dropdown
+
+import pl.treksoft.kvision.html.Div
+
+/**
+ * Menu separator component.
+ *
+ * @constructor
+ * @param classes a set of CSS class names
+ */
+open class Separator(classes: Set<String> = setOf()) : Div(classes = classes + "dropdown-divider") {
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun ContextMenu.separator(classes: Set<String> = setOf()): Separator {
+ val separator = Separator(classes)
+ this.add(separator)
+ return separator
+ }
+
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun DropDown.separator(classes: Set<String> = setOf()): Separator {
+ val separator = Separator(classes)
+ this.add(separator)
+ return separator
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt
new file mode 100644
index 00000000..5f5a1a80
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt
@@ -0,0 +1,121 @@
+/*
+ * 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.modal
+
+import pl.treksoft.kvision.core.Widget
+import pl.treksoft.kvision.html.Align
+import pl.treksoft.kvision.html.ButtonStyle
+import pl.treksoft.kvision.html.Button
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+import pl.treksoft.kvision.utils.ENTER_KEY
+
+/**
+ * Alert window based on Bootstrap modal.
+ *
+ * @constructor
+ * @param caption window title
+ * @param text window content text.
+ * @param rich determines if [text] can contain HTML code
+ * @param align text align
+ * @param size modal window size
+ * @param animation determines if animations are used
+ * @param callback a function called after closing window with OK button
+ */
+open class Alert(
+ caption: String? = null, text: String? = null, rich: Boolean = false,
+ align: Align? = null, size: ModalSize? = null, animation: Boolean = true,
+ private val callback: (() -> Unit)? = null
+) : Modal(caption, true, size, animation) {
+
+ /**
+ * Window content text.
+ */
+ var text
+ get() = contentTag.content
+ set(value) {
+ contentTag.content = value
+ }
+ /**
+ * Determines if [text] can contain HTML code.
+ */
+ var rich
+ get() = contentTag.rich
+ set(value) {
+ contentTag.rich = value
+ }
+ /**
+ * Text align.
+ */
+ var align
+ get() = contentTag.align
+ set(value) {
+ contentTag.align = value
+ }
+
+ private val contentTag = Tag(TAG.DIV, text, rich, align)
+
+ init {
+ body.add(contentTag)
+ val okButton = Button("OK", "ok", ButtonStyle.PRIMARY)
+ okButton.setEventListener {
+ click = {
+ hide()
+ }
+ }
+ this.addButton(okButton)
+ this.setEventListener {
+ keydown = { e ->
+ if (e.keyCode == ENTER_KEY) {
+ hide()
+ }
+ }
+ }
+ }
+
+ override fun hide(): Widget {
+ super.hide()
+ this.callback?.invoke()
+ return this
+ }
+
+ companion object {
+ /**
+ * Helper function for opening Alert window.
+ * @param caption window title
+ * @param text window content text.
+ * @param rich determines if [text] can contain HTML code
+ * @param align text align
+ * @param size modal window size
+ * @param animation determines if animations are used
+ * @param callback a function called after closing window with OK button
+ */
+ @Suppress("LongParameterList")
+ fun show(
+ caption: String? = null, text: String? = null, rich: Boolean = false,
+ align: Align? = null, size: ModalSize? = null, animation: Boolean = true,
+ callback: (() -> Unit)? = null
+ ) {
+ Alert(caption, text, rich, align, size, animation, callback).show()
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt
new file mode 100644
index 00000000..5f0440a6
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.modal
+
+import com.github.snabbdom.VNode
+import pl.treksoft.kvision.KVManager
+import pl.treksoft.kvision.core.StringBoolPair
+import pl.treksoft.kvision.core.StringPair
+import pl.treksoft.kvision.core.Widget
+
+/**
+ * Helper class for close icon component.
+ */
+open class CloseIcon : Widget(setOf()) {
+
+ override fun render(): VNode {
+ return render("button", arrayOf(KVManager.virtualize("<span aria-hidden='true'>&times;</span>")))
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ cl.add("close" to true)
+ return cl
+ }
+
+ override fun getSnAttrs(): List<StringPair> {
+ return super.getSnAttrs() + listOf("type" to "button", "aria-label" to "Close")
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt
new file mode 100644
index 00000000..e16ca87e
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt
@@ -0,0 +1,176 @@
+/*
+ * 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.modal
+
+import pl.treksoft.kvision.html.Align
+import pl.treksoft.kvision.html.Button
+import pl.treksoft.kvision.html.ButtonStyle
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+
+/**
+ * Confirm window based on Bootstrap modal.
+ *
+ * @constructor
+ * @param caption window title
+ * @param text window content text.
+ * @param rich determines if [text] can contain HTML code
+ * @param align text align
+ * @param size modal window size
+ * @param animation determines if animations are used
+ * @param cancelVisible determines if Cancel button is visible
+ * @param yesTitle yes button text
+ * @param noTitle no button text
+ * @param cancelTitle cancel button text
+ * @param noCallback a function called after closing window with No button
+ * @param yesCallback a function called after closing window with Yes button
+ */
+open class Confirm(
+ caption: String? = null, text: String? = null, rich: Boolean = false,
+ align: Align? = null, size: ModalSize? = null, animation: Boolean = true,
+ cancelVisible: Boolean = false, yesTitle: String = "Yes", noTitle: String = "No", cancelTitle: String = "Cancel",
+ private val noCallback: (() -> Unit)? = null,
+ private val yesCallback: (() -> Unit)? = null
+) : Modal(caption, false, size, animation, false) {
+ /**
+ * Window content text.
+ */
+ var text
+ get() = contentTag.content
+ set(value) {
+ contentTag.content = value
+ }
+ /**
+ * Determines if [text] can contain HTML code.
+ */
+ var rich
+ get() = contentTag.rich
+ set(value) {
+ contentTag.rich = value
+ }
+ /**
+ * Text align.
+ */
+ var align
+ get() = contentTag.align
+ set(value) {
+ contentTag.align = value
+ }
+ /**
+ * Determines if Cancel button is visible.
+ */
+ var cancelVisible by refreshOnUpdate(cancelVisible) { refreshCancelButton() }
+
+ /**
+ * Yes button text.
+ */
+ var yesTitle
+ get() = yesButton.text
+ set(value) {
+ yesButton.text = value
+ }
+
+ /**
+ * No button text.
+ */
+ var noTitle
+ get() = noButton.text
+ set(value) {
+ noButton.text = value
+ }
+
+ /**
+ * Cancel button text.
+ */
+ var cancelTitle
+ get() = cancelButton.text
+ set(value) {
+ cancelButton.text = value
+ }
+
+ private val contentTag = Tag(TAG.DIV, text, rich, align)
+ private val cancelButton = Button(cancelTitle, "remove")
+ private val noButton = Button(noTitle, "ban-circle")
+ private val yesButton = Button(yesTitle, "ok", ButtonStyle.PRIMARY)
+
+ init {
+ body.add(contentTag)
+ cancelButton.setEventListener {
+ click = {
+ hide()
+ }
+ }
+ this.addButton(cancelButton)
+ noButton.setEventListener {
+ click = {
+ hide()
+ noCallback?.invoke()
+ }
+ }
+ this.addButton(noButton)
+ yesButton.setEventListener {
+ click = {
+ hide()
+ yesCallback?.invoke()
+ }
+ }
+ this.addButton(yesButton)
+ refreshCancelButton()
+ }
+
+ private fun refreshCancelButton() {
+ if (cancelVisible) {
+ cancelButton.show()
+ closeIcon.show()
+ } else {
+ cancelButton.hide()
+ closeIcon.hide()
+ }
+ }
+
+ companion object {
+ /**
+ * Helper function for opening Confirm window.
+ * @param caption window title
+ * @param text window content text.
+ * @param rich determines if [text] can contain HTML code
+ * @param align text align
+ * @param size modal window size
+ * @param animation determines if animations are used
+ * @param cancelVisible determines if Cancel button is visible
+ * @param noCallback a function called after closing window with No button
+ * @param yesCallback a function called after closing window with Yes button
+ */
+ @Suppress("LongParameterList")
+ fun show(
+ caption: String? = null, text: String? = null, rich: Boolean = false,
+ align: Align? = null, size: ModalSize? = null, animation: Boolean = true,
+ cancelVisible: Boolean = false, yesTitle: String = "Yes", noTitle: String = "No",
+ cancelTitle: String = "Cancel", noCallback: (() -> Unit)? = null, yesCallback: (() -> Unit)? = null
+ ) {
+ Confirm(
+ caption, text, rich, align, size, animation, cancelVisible, yesTitle, noTitle, cancelTitle,
+ noCallback, yesCallback
+ ).show()
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt
new file mode 100644
index 00000000..08fc7aa8
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt
@@ -0,0 +1,292 @@
+/*
+ * 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.modal
+
+import com.github.snabbdom.VNode
+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.core.Widget
+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
+
+/**
+ * Modal window sizes.
+ */
+enum class ModalSize(val className: String) {
+ XLARGE("modal-xl"),
+ LARGE("modal-lg"),
+ SMALL("modal-sm")
+}
+
+/**
+ * Configurable modal window based on Bootstrap modal.
+ *
+ * @constructor
+ * @param caption window title
+ * @param closeButton determines if Close button is visible
+ * @param size modal window size
+ * @param animation determines if animations are used
+ * @param escape determines if dialog can be closed with Esc key
+ * @param classes a set of CSS class names
+ * @param init an initializer extension function
+ */
+@Suppress("TooManyFunctions")
+open class Modal(
+ caption: String? = null, closeButton: Boolean = true,
+ size: ModalSize? = null, animation: Boolean = true, private val escape: Boolean = true,
+ classes: Set<String> = setOf(), init: (Modal.() -> Unit)? = null
+) : SimplePanel(classes) {
+
+ override var parent: Container? = Root.getFirstRoot()
+
+ /**
+ * Window caption text.
+ */
+ var caption
+ get() = captionTag.content
+ set(value) {
+ captionTag.content = value
+ checkHeaderVisibility()
+ }
+ /**
+ * Determines if Close button is visible.
+ */
+ var closeButton
+ get() = closeIcon.visible
+ set(value) {
+ closeIcon.visible = value
+ checkHeaderVisibility()
+ }
+ /**
+ * Window size.
+ */
+ var size
+ get() = dialog.size
+ set(value) {
+ dialog.size = value
+ }
+ /**
+ * Determines if animations are used.
+ */
+ var animation by refreshOnUpdate(animation)
+
+ private val dialog = ModalDialog(size)
+ private val header = SimplePanel(setOf("modal-header"))
+ /**
+ * @suppress
+ * Internal property.
+ */
+ protected val closeIcon = CloseIcon()
+ private val captionTag = Tag(TAG.H5, caption, classes = setOf("modal-title"))
+ /**
+ * @suppress
+ * Internal property.
+ */
+ protected val body = SimplePanel(setOf("modal-body"))
+ private val footer = SimplePanel(setOf("modal-footer"))
+
+ init {
+ this.hide()
+ this.role = "dialog"
+ this.tabindex = -1
+ this.addInternal(dialog)
+ val content = SimplePanel(setOf("modal-content"))
+ dialog.role = "document"
+ dialog.add(content)
+ closeIcon.visible = closeButton
+ closeIcon.setEventListener {
+ click = {
+ hide()
+ }
+ }
+ header.add(captionTag)
+ header.add(closeIcon)
+ checkHeaderVisibility()
+ content.add(header)
+ content.add(body)
+ content.add(footer)
+ @Suppress("LeakingThis")
+ addModal(this)
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ private fun checkHeaderVisibility() {
+ if (!closeButton && caption == null) {
+ header.hide()
+ } else {
+ header.show()
+ }
+ }
+
+ override fun add(child: Component): SimplePanel {
+ body.add(child)
+ return this
+ }
+
+ override fun addAll(children: List<Component>): SimplePanel {
+ body.addAll(children)
+ return this
+ }
+
+ override fun remove(child: Component): SimplePanel {
+ body.remove(child)
+ return this
+ }
+
+ override fun removeAll(): SimplePanel {
+ body.removeAll()
+ return this
+ }
+
+ override fun getChildren(): List<Component> {
+ return body.getChildren()
+ }
+
+ /**
+ * Adds given button to the bottom section of dialog window.
+ * @param button a [Button] component
+ * @return this modal
+ */
+ open fun addButton(button: Button): Modal {
+ footer.add(button)
+ return this
+ }
+
+ /**
+ * Removes given button from the bottom section of dialog window.
+ * @param button a [Button] component
+ * @return this modal
+ */
+ open fun removeButton(button: Button): Modal {
+ footer.remove(button)
+ return this
+ }
+
+ /**
+ * Removes all buttons from the bottom section of dialog window.
+ * @return this modal
+ */
+ open fun removeAllButtons(): Modal {
+ footer.removeAll()
+ return this
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ cl.add("modal" to true)
+ if (animation) {
+ cl.add("fade" to true)
+ }
+ return cl
+ }
+
+ @Suppress("UnsafeCastFromDynamic")
+ override fun afterInsert(node: VNode) {
+ getElementJQueryD()?.modal(obj {
+ keyboard = escape
+ backdrop = if (escape) "true" else "static"
+ })
+ this.getElementJQuery()?.on("show.bs.modal") { e, _ ->
+ this.dispatchEvent("showBsModal", obj { detail = e })
+ }
+ this.getElementJQuery()?.on("shown.bs.modal") { e, _ ->
+ this.dispatchEvent("shownBsModal", obj { detail = e })
+ }
+ this.getElementJQuery()?.on("hide.bs.modal") { e, _ ->
+ this.dispatchEvent("hideBsModal", obj { detail = e })
+ }
+ this.getElementJQuery()?.on("hidden.bs.modal") { e, _ ->
+ this.visible = false
+ hide()
+ this.dispatchEvent("hiddenBsModal", obj { detail = e })
+ }
+ }
+
+ override fun hide(): Widget {
+ if (visible) hideInternal()
+ return super.hide()
+ }
+
+ /**
+ * Toggle modal window visibility.
+ */
+ open fun toggle() {
+ if (visible)
+ hide()
+ else
+ show()
+ }
+
+ @Suppress("UnsafeCastFromDynamic")
+ private fun showInternal() {
+ getElementJQueryD()?.modal("show")
+ }
+
+ @Suppress("UnsafeCastFromDynamic")
+ private fun hideInternal() {
+ getElementJQueryD()?.modal("hide")
+ }
+
+ override fun clearParent(): Widget {
+ this.parent = null
+ return this
+ }
+
+ override fun getRoot(): Root? {
+ return this.parent?.getRoot()
+ }
+
+ override fun dispose() {
+ removeModal(this)
+ }
+}
+
+/**
+ * Internal helper class for modal content.
+ *
+ * @constructor
+ * @param size modal window size
+ */
+internal class ModalDialog(size: ModalSize?) : SimplePanel(setOf("modal-dialog")) {
+
+ /**
+ * Modal window size.
+ */
+ var size by refreshOnUpdate(size)
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ size?.let {
+ cl.add(it.className to true)
+ }
+ return cl
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt
new file mode 100644
index 00000000..e0da480d
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt
@@ -0,0 +1,110 @@
+/*
+ * 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.navbar
+
+import pl.treksoft.kvision.core.ResString
+import pl.treksoft.kvision.core.StringBoolPair
+import pl.treksoft.kvision.html.Div
+import pl.treksoft.kvision.html.Link
+
+/**
+ * The Bootstrap Nav container.
+ *
+ * @constructor
+ * @param rightAlign determines if the nav is aligned to the right
+ * @param classes a set of CSS class names
+ * @param init an initializer extension function
+ */
+open class Nav(rightAlign: Boolean = false, classes: Set<String> = setOf(), init: (Nav.() -> Unit)? = null) :
+ Div(classes = classes) {
+
+ /**
+ * Determines if the nav is aligned to the right.
+ */
+ var rightAlign by refreshOnUpdate(rightAlign)
+
+ init {
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ cl.add("navbar-nav" to true)
+ if (rightAlign) {
+ cl.add("ml-auto" to true)
+ }
+ return cl
+ }
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Navbar.nav(
+ rightAlign: Boolean = false, classes: Set<String> = setOf(), init: (Nav.() -> Unit)? = null
+ ): Nav {
+ val nav = Nav(rightAlign, classes).apply { init?.invoke(this) }
+ 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/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt
new file mode 100644
index 00000000..45454cc8
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt
@@ -0,0 +1,72 @@
+/*
+ * 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.navbar
+
+import pl.treksoft.kvision.core.StringBoolPair
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+
+/**
+ * The Bootstrap Nav form container.
+ *
+ * @constructor
+ * @param rightAlign determines if the nav form is aligned to the right
+ * @param classes a set of CSS class names
+ * @param init an initializer extension function
+ */
+open class NavForm(rightAlign: Boolean = false, classes: Set<String> = setOf(), init: (NavForm.() -> Unit)? = null) :
+ Tag(TAG.FORM, classes = classes) {
+
+ /**
+ * Determines if the nav form is aligned to the right.
+ */
+ var rightAlign by refreshOnUpdate(rightAlign)
+
+ init {
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ cl.add("form-inline" to true)
+ if (rightAlign) {
+ cl.add("ml-auto" to true)
+ }
+ return cl
+ }
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Navbar.navForm(
+ rightAlign: Boolean = false, classes: Set<String> = setOf(), init: (NavForm.() -> Unit)? = null
+ ): NavForm {
+ val navForm = NavForm(rightAlign, classes).apply { init?.invoke(this) }
+ this.add(navForm)
+ return navForm
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt
new file mode 100644
index 00000000..34a9dbe2
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt
@@ -0,0 +1,229 @@
+/*
+ * 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.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.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("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"),
+}
+
+/**
+ * The Bootstrap Navbar container.
+ *
+ * @constructor
+ * @param label the navbar label
+ * @param type the navbar type
+ * @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,
+ expand: NavbarExpand? = NavbarExpand.LG,
+ nColor: NavbarColor = NavbarColor.LIGHT,
+ bgColor: BsBgColor = BsBgColor.LIGHT,
+ classes: Set<String> = setOf(), init: (Navbar.() -> Unit)? = null
+) : SimplePanel(classes) {
+
+ /**
+ * The navbar header label.
+ */
+ var label
+ get() = if (brandLink.visible) brandLink.label else null
+ set(value) {
+ if (value != null) {
+ brandLink.label = value
+ brandLink.show()
+ } else {
+ brandLink.hide()
+ }
+ }
+
+ /**
+ * The navbar type.
+ */
+ var type by refreshOnUpdate(type)
+ /**
+ * The navbar responsive behavior.
+ */
+ 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"
+
+ private val brandLink = Link(label ?: "", "#", classes = setOf("navbar-brand"))
+ internal val container = SimplePanel(setOf("collapse", "navbar-collapse")) {
+ id = idc
+ }
+
+ init {
+ addInternal(brandLink)
+ addInternal(NavbarButton(idc))
+ addInternal(container)
+ if (label == null) brandLink.hide()
+ counter++
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ override fun render(): VNode {
+ return render("nav", childrenVNodes())
+ }
+
+ override fun add(child: Component): Navbar {
+ container.add(child)
+ return this
+ }
+
+ override fun addAll(children: List<Component>): Navbar {
+ container.addAll(children)
+ return this
+ }
+
+ override fun remove(child: Component): Navbar {
+ container.remove(child)
+ return this
+ }
+
+ override fun removeAll(): Navbar {
+ container.removeAll()
+ return this
+ }
+
+ override fun getChildren(): List<Component> {
+ return container.getChildren()
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ cl.add("navbar" to true)
+ type?.let {
+ cl.add(it.navbarType to true)
+ }
+ expand?.let {
+ cl.add(it.navbarExpand to true)
+ }
+ cl.add(nColor.navbarColor to true)
+ cl.add(bgColor.className to true)
+ return cl
+ }
+
+ companion object {
+ internal var counter = 0
+
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Container.navbar(
+ label: String? = null,
+ type: NavbarType? = null,
+ 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, 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
+ }
+ }
+}
+
+/**
+ * @suppress
+ * Internal component.
+ * The Bootstrap Navbar header button.
+ */
+internal class NavbarButton(private val idc: String, private val toggle: String = "Toggle navigation") :
+ SimplePanel(setOf("navbar-toggler")) {
+
+ init {
+ span(classes = setOf("navbar-toggler-icon"))
+ }
+
+ override fun render(): VNode {
+ return render("button", childrenVNodes())
+ }
+
+ override fun getSnAttrs(): List<StringPair> {
+ return super.getSnAttrs() + listOf(
+ "type" to "button",
+ "data-toggle" to "collapse",
+ "data-target" to "#$idc",
+ "aria-controls" to idc,
+ "aria-expanded" to "false",
+ "aria-label" to toggle
+ )
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt
new file mode 100644
index 00000000..2ff6fa19
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt
@@ -0,0 +1,185 @@
+/*
+ * 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.panel
+
+import pl.treksoft.kvision.core.Component
+import pl.treksoft.kvision.core.Container
+import pl.treksoft.kvision.core.WidgetWrapper
+import pl.treksoft.kvision.html.Align
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+
+/**
+ * Bootstrap grid sizes.
+ */
+enum class GridSize(internal val size: String) {
+ SM("sm"),
+ MD("md"),
+ LG("lg"),
+ XL("xs")
+}
+
+internal const val MAX_COLUMNS = 12
+
+internal data class WidgetParam(val widget: Component, val size: Int, val offset: Int)
+
+/**
+ * The container with support for Bootstrap responsive grid layout.
+ *
+ * @constructor
+ * @param gridSize grid size
+ * @param rows number of rows
+ * @param cols number of columns
+ * @param align text align of grid cells
+ * @param classes a set of CSS class names
+ * @param init an initializer extension function
+ */
+open class ResponsiveGridPanel(
+ private val gridSize: GridSize = GridSize.MD,
+ private var rows: Int = 0, private var cols: Int = 0, align: Align? = null,
+ classes: Set<String> = setOf(), init: (ResponsiveGridPanel.() -> Unit)? = null
+) : SimplePanel(classes + "container-fluid") {
+
+ /**
+ * Text align of grid cells.
+ */
+ var align by refreshOnUpdate(align) { refreshRowContainers() }
+
+ internal val map = mutableMapOf<Int, MutableMap<Int, WidgetParam>>()
+ private var auto: Boolean = true
+
+ init {
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ /**
+ * Adds child component to the grid.
+ * @param child child component
+ * @param col column number
+ * @param row row number
+ * @param size cell size (colspan)
+ * @param offset cell offset
+ * @return this container
+ */
+ open fun add(child: Component, col: Int, row: Int, size: Int = 0, offset: Int = 0): ResponsiveGridPanel {
+ 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()
+ return this
+ }
+
+ override fun add(child: Component): ResponsiveGridPanel {
+ return this.add(child, this.cols, 0)
+ }
+
+ override fun addAll(children: List<Component>): ResponsiveGridPanel {
+ children.forEach { this.add(it) }
+ return this
+ }
+
+ @Suppress("NestedBlockDepth")
+ override fun remove(child: Component): ResponsiveGridPanel {
+ map.values.forEach { row ->
+ row.filterValues { it.widget == child }
+ .forEach { (i, _) -> row.remove(i) }
+ }
+ refreshRowContainers()
+ return this
+ }
+
+ /**
+ * Removes child component at given location (column, row).
+ * @param col column number
+ * @param row row number
+ * @return this container
+ */
+ open fun removeAt(col: Int, row: Int): ResponsiveGridPanel {
+ map[row]?.remove(col)
+ refreshRowContainers()
+ return this
+ }
+
+ @Suppress("ComplexMethod", "NestedBlockDepth")
+ private fun refreshRowContainers() {
+ singleRender {
+ clearRowContainers()
+ val num = MAX_COLUMNS / cols
+ for (i in 1..rows) {
+ val rowContainer = SimplePanel(setOf("row"))
+ val row = map[i]
+ if (row != null) {
+ (1..cols).map { row[it] }.forEach { wp ->
+ if (auto) {
+ val widget = wp?.widget?.let {
+ WidgetWrapper(it, setOf("col-" + gridSize.size + "-" + num))
+ } ?: Tag(TAG.DIV, classes = setOf("col-" + gridSize.size + "-" + num))
+ align?.let {
+ widget.addCssClass(it.className)
+ }
+ rowContainer.add(widget)
+ } else {
+ if (wp != null) {
+ 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("offset-" + gridSize.size + "-" + wp.offset)
+ }
+ align?.let {
+ widget.addCssClass(it.className)
+ }
+ rowContainer.add(widget)
+ }
+ }
+ }
+ }
+ addInternal(rowContainer)
+ }
+ }
+ }
+
+ private fun clearRowContainers() {
+ children.forEach { it.dispose() }
+ removeAll()
+ }
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Container.responsiveGridPanel(
+ gridSize: GridSize = GridSize.MD,
+ rows: Int = 0, cols: Int = 0, align: Align? = null,
+ classes: Set<String> = setOf(), init: (ResponsiveGridPanel.() -> Unit)? = null
+ ): ResponsiveGridPanel {
+ val responsiveGridPanel = ResponsiveGridPanel(gridSize, rows, cols, align, classes, init)
+ this.add(responsiveGridPanel)
+ return responsiveGridPanel
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt
new file mode 100644
index 00000000..2009e4fc
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt
@@ -0,0 +1,273 @@
+/*
+ * 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.panel
+
+import pl.treksoft.kvision.core.Component
+import pl.treksoft.kvision.core.Container
+import pl.treksoft.kvision.core.ResString
+import pl.treksoft.kvision.core.WidgetWrapper
+import pl.treksoft.kvision.html.Icon
+import pl.treksoft.kvision.html.Link.Companion.link
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+import pl.treksoft.kvision.routing.routing
+import pl.treksoft.kvision.utils.obj
+import pl.treksoft.kvision.html.Icon.Companion.icon as cicon
+
+/**
+ * Tab position.
+ */
+enum class TabPosition {
+ TOP,
+ LEFT,
+ RIGHT
+}
+
+/**
+ * Left or right tab size.
+ */
+enum class SideTabSize {
+ SIZE_1,
+ SIZE_2,
+ SIZE_3,
+ SIZE_4,
+ SIZE_5,
+ SIZE_6
+}
+
+/**
+ * The container rendering it's children as tabs.
+ *
+ * It supports activating children by a JavaScript route.
+ *
+ * @constructor
+ * @param tabPosition tab position
+ * @param sideTabSize side tab size
+ * @param scrollableTabs determines if tabs are scrollable (default: false)
+ * @param classes a set of CSS class names
+ * @param init an initializer extension function
+ */
+open class TabPanel(
+ private val tabPosition: TabPosition = TabPosition.TOP,
+ private val sideTabSize: SideTabSize = SideTabSize.SIZE_3,
+ scrollableTabs: Boolean = false,
+ classes: Set<String> = setOf(),
+ init: (TabPanel.() -> Unit)? = null
+) : SimplePanel(classes) {
+
+ /**
+ * The index of active (visible) tab.
+ */
+ var activeIndex
+ get() = content.activeIndex
+ set(value) {
+ if (content.activeIndex != value) {
+ content.activeIndex = value
+ }
+ 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", "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)
+
+ internal val childrenMap = mutableMapOf<Int, Component>()
+
+ init {
+ when (tabPosition) {
+ TabPosition.TOP -> {
+ this.addInternal(nav)
+ this.addInternal(content)
+ }
+ TabPosition.LEFT -> {
+ this.addSurroundingCssClass("container-fluid")
+ this.addCssClass("row")
+ val sizes = calculateSideClasses()
+ 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.addSurroundingCssClass("container-fluid")
+ this.addCssClass("row")
+ val sizes = calculateSideClasses()
+ this.addInternal(WidgetWrapper(content, setOf(sizes.second, "pl-0", "pr-0")))
+ this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "pl-0", "pr-0")))
+ }
+ }
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ private fun calculateSideClasses(): Pair<String, String> {
+ return when (sideTabSize) {
+ 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")
+ }
+ }
+
+ /**
+ * Adds new tab and optionally bounds it's activation to a given route.
+ * @param title title of the tab
+ * @param panel child component
+ * @param icon icon of the tab
+ * @param image image of the tab
+ * @param closable determines if this tab is closable
+ * @param route JavaScript route to activate given child
+ * @return current container
+ */
+ open fun addTab(
+ title: String, panel: Component, icon: String? = null,
+ image: ResString? = null, closable: Boolean = false, route: String? = null
+ ): TabPanel {
+ val currentIndex = counter++
+ childrenMap[currentIndex] = panel
+ val tag = Tag(TAG.LI, classes = setOf("nav-item")) {
+ link(title, "#", icon, image, classes = setOf("nav-link")) {
+ if (closable) {
+ cicon("fas fa-times") {
+ addCssClass("kv-tab-close")
+ setEventListener<Icon> {
+ click = { e ->
+ val actIndex = this@TabPanel.content.getChildren().indexOf(childrenMap[currentIndex])
+ e.asDynamic().data = actIndex
+ @Suppress("UnsafeCastFromDynamic")
+ if (this@TabPanel.dispatchEvent(
+ "tabClosing",
+ obj { detail = e; cancelable = true }) != false
+ ) {
+ this@TabPanel.removeTab(actIndex)
+ this@TabPanel.dispatchEvent("tabClosed", obj { detail = e })
+ }
+ e.stopPropagation()
+ }
+ }
+ }
+ }
+ }
+ setEventListener {
+ click = { e ->
+ activeIndex = this@TabPanel.content.getChildren().indexOf(childrenMap[currentIndex])
+ e.preventDefault()
+ if (route != null) {
+ routing.navigate(route)
+ }
+ }
+ }
+ }
+ nav.add(tag)
+ 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.getChildren().indexOf(childrenMap[currentIndex]) })
+ .resolve()
+ }
+ return this
+ }
+
+ /**
+ * Removes tab at given index.
+ */
+ open fun removeTab(index: Int): TabPanel {
+ nav.remove(nav.getChildren()[index])
+ childrenMap.filter { it.value == content.getChildren()[index] }.keys.firstOrNull()?.let {
+ childrenMap.remove(it)
+ }
+ content.remove(content.getChildren()[index])
+ activeIndex = content.activeIndex
+ return this
+ }
+
+ override fun add(child: Component): TabPanel {
+ return addTab("", child)
+ }
+
+ override fun addAll(children: List<Component>): TabPanel {
+ children.forEach { add(it) }
+ return this
+ }
+
+ override fun remove(child: Component): TabPanel {
+ val index = content.getChildren().indexOf(child)
+ return removeTab(index)
+ }
+
+ /**
+ * Returns child component by tab index.
+ * @param index tab index
+ */
+ open fun getChildComponent(index: Int): Component? {
+ return content.getChildren()[index]
+ }
+
+ /**
+ * Returns tab header component by tab index.
+ * @param index tab index
+ */
+ open fun getNavComponent(index: Int): Tag? {
+ return nav.getChildren()[index] as? Tag
+ }
+
+ override fun removeAll(): TabPanel {
+ content.removeAll()
+ nav.removeAll()
+ childrenMap.clear()
+ refresh()
+ return this
+ }
+
+ companion object {
+ internal var counter = 0
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Container.tabPanel(
+ tabPosition: TabPosition = TabPosition.TOP,
+ sideTabSize: SideTabSize = SideTabSize.SIZE_3,
+ scrollableTabs: Boolean = false,
+ classes: Set<String> = setOf(),
+ init: (TabPanel.() -> Unit)? = null
+ ): TabPanel {
+ val tabPanel = TabPanel(tabPosition, sideTabSize, scrollableTabs, classes, init)
+ this.add(tabPanel)
+ return tabPanel
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt
new file mode 100644
index 00000000..4d0f4b93
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt
@@ -0,0 +1,162 @@
+/*
+ * 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.progress
+
+import pl.treksoft.kvision.core.Container
+import pl.treksoft.kvision.html.Align
+import pl.treksoft.kvision.panel.SimplePanel
+
+/**
+ * The Bootstrap progress bar.
+ *
+ * @constructor
+ * @param progress the current progress
+ * @param min the minimal progress
+ * @param max the maximal progress
+ * @param style the style of the progress bar
+ * @param striped determines if the progress bar is striped
+ * @param animated determines if the progress bar is animated
+ * @param content element text
+ * @param rich determines if content can contain HTML code
+ * @param align content align
+ * @param classes a set of CSS class names
+ * @param init an initializer extension function
+ */
+open class ProgressBar(
+ progress: Int, min: Int = DEFAULT_MIN, max: Int = DEFAULT_MAX, style: ProgressBarStyle? = null,
+ striped: Boolean = false, animated: Boolean = false, content: String? = null,
+ rich: Boolean = false, align: Align? = null,
+ classes: Set<String> = setOf(), init: (ProgressBar.() -> Unit)? = null
+) :
+ SimplePanel(classes + "progress") {
+
+ /**
+ * The current progress.
+ */
+ var progress
+ get() = indicator.progress
+ set(value) {
+ indicator.progress = value
+ }
+ /**
+ * The minimal progress.
+ */
+ var min
+ get() = indicator.min
+ set(value) {
+ indicator.min = value
+ }
+ /**
+ * The maximal progress.
+ */
+ var max
+ get() = indicator.max
+ set(value) {
+ indicator.max = value
+ }
+ /**
+ * The style of the progress bar.
+ */
+ var style
+ get() = indicator.style
+ set(value) {
+ indicator.style = value
+ }
+ /**
+ * Determines if the progress bar is striped.
+ */
+ var striped
+ get() = indicator.striped
+ set(value) {
+ indicator.striped = value
+ }
+ /**
+ * Determines if the progress bar is animated.
+ */
+ var animated
+ get() = indicator.animated
+ set(value) {
+ indicator.animated = value
+ }
+ /**
+ * Text content of the progress bar.
+ */
+ var content
+ get() = indicator.content
+ set(value) {
+ indicator.content = value
+ }
+ /**
+ * Determines if [content] can contain HTML code.
+ */
+ var rich
+ get() = indicator.rich
+ set(value) {
+ indicator.rich = value
+ }
+ /**
+ * Text align of the progress bar.
+ */
+ var align
+ get() = indicator.align
+ set(value) {
+ indicator.align = value
+ }
+
+ internal val indicator = ProgressIndicator(progress, min, max, style, striped, animated, content, rich, align)
+
+ init {
+ addInternal(indicator)
+
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Container.progressBar(
+ progress: Int, min: Int = DEFAULT_MIN, max: Int = DEFAULT_MAX, style: ProgressBarStyle? = null,
+ striped: Boolean = false, animated: Boolean = false,
+ content: String? = null, rich: Boolean = false, align: Align? = null,
+ classes: Set<String> = setOf(), init: (ProgressBar.() -> Unit)? = null
+ ): ProgressBar {
+ val progressBar = ProgressBar(
+ progress,
+ min,
+ max,
+ style,
+ striped,
+ animated,
+ content,
+ rich,
+ align,
+ classes
+ ).apply { init?.invoke(this) }
+ this.add(progressBar)
+ return progressBar
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt
new file mode 100644
index 00000000..256d15d7
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressIndicator.kt
@@ -0,0 +1,125 @@
+/*
+ * 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.progress
+
+import pl.treksoft.kvision.core.StringBoolPair
+import pl.treksoft.kvision.core.StringPair
+import pl.treksoft.kvision.html.Align
+import pl.treksoft.kvision.html.Div
+import pl.treksoft.kvision.utils.perc
+
+/**
+ * Progress bar styles.
+ */
+enum class ProgressBarStyle(internal val className: String) {
+ SUCCESS("progress-bar-success"),
+ INFO("progress-bar-info"),
+ WARNING("progress-bar-warning"),
+ DANGER("progress-bar-danger")
+}
+
+internal const val DEFAULT_MIN = 0
+internal const val DEFAULT_MAX = 100
+
+
+/**
+ * The Bootstrap progress bar indicator.
+ *
+ * @constructor
+ * @param progress the current progress
+ * @param min the minimal progress
+ * @param max the maximal progress
+ * @param style the style of the progress bar indicator
+ * @param striped determines if the progress bar indicator is striped
+ * @param animated determines if the progress bar indicator is animated
+ * @param content element text
+ * @param rich determines if [content] can contain HTML code
+ * @param align content align
+ * @param classes a set of CSS class names
+ */
+internal class ProgressIndicator(
+ progress: Int, min: Int = DEFAULT_MIN, max: Int = DEFAULT_MAX, style: ProgressBarStyle? = null,
+ striped: Boolean = false, animated: Boolean = false,
+ content: String? = null, rich: Boolean = false, align: Align? = null,
+ classes: Set<String> = setOf()
+) :
+ Div(content, rich, align, classes) {
+
+ /**
+ * The current progress.
+ */
+ var progress by refreshOnUpdate(progress) { refreshWidth() }
+ /**
+ * The minimal progress.
+ */
+ var min by refreshOnUpdate(min) { refreshWidth() }
+ /**
+ * The maximal progress.
+ */
+ var max by refreshOnUpdate(max) { refreshWidth() }
+ /**
+ * The style of the progress indicator.
+ */
+ var style by refreshOnUpdate(style)
+ /**
+ * Determines if the progress indicator is striped.
+ */
+ var striped by refreshOnUpdate(striped)
+ /**
+ * Determines if the progress indicator is animated.
+ */
+ var animated by refreshOnUpdate(animated)
+
+ init {
+ role = "progressbar"
+ refreshWidth()
+ }
+
+ private fun refreshWidth() {
+ val value = (if (max - min > 0) (progress - min) * DEFAULT_MAX.toFloat() / (max - min) else 0f).toInt()
+ val percent = if (value < 0) 0 else if (value > DEFAULT_MAX) DEFAULT_MAX else value
+ width = percent.perc
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ cl.add("progress-bar" to true)
+ style?.let {
+ cl.add(it.className to true)
+ }
+ if (striped || animated) {
+ cl.add("progress-bar-striped" to true)
+ }
+ if (animated) {
+ cl.add("active" to true)
+ }
+ return cl
+ }
+
+ override fun getSnAttrs(): List<StringPair> {
+ val sn = super.getSnAttrs().toMutableList()
+ sn.add("aria-valuenow" to "$progress")
+ sn.add("aria-valuemin" to "$min")
+ sn.add("aria-valuemax" to "$max")
+ return sn
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt
new file mode 100644
index 00000000..2aef9e63
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt
@@ -0,0 +1,109 @@
+/*
+ * 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.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")
+}
+
+/**
+ * The Bootstrap button group.
+ *
+ * @constructor
+ * @param size button group size
+ * @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, vertical: Boolean = false,
+ classes: Set<String> = setOf(), init: (ButtonGroup.() -> Unit)? = null
+) : SimplePanel(classes) {
+
+ /**
+ * Button group size.
+ */
+ var size by refreshOnUpdate(size)
+ /**
+ * Vertical alignment.
+ */
+ var vertical by refreshOnUpdate(vertical)
+
+ init {
+ role = "group"
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ if (vertical) {
+ cl.add("btn-group-vertical" to true)
+ } else {
+ cl.add("btn-group" to true)
+ }
+ size?.let {
+ cl.add(it.className to true)
+ }
+ return cl
+ }
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Container.buttonGroup(
+ 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(this.size, this.vertical, classes).apply {
+ marginRight = this@buttonGroup.spacing.px
+ init?.invoke(this)
+ }
+ this.add(group)
+ return group
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt
new file mode 100644
index 00000000..13ed8972
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.toolbar
+
+import pl.treksoft.kvision.core.Container
+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") {
+
+ init {
+ role = "toolbar"
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * 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(size, spacing, vertical, classes).apply { init?.invoke(this) }
+ this.add(toolbar)
+ return toolbar
+ }
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt
new file mode 100644
index 00000000..a3ceaf61
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MaximizeIcon.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.window
+
+import com.github.snabbdom.VNode
+import pl.treksoft.kvision.KVManager
+import pl.treksoft.kvision.core.StringBoolPair
+import pl.treksoft.kvision.core.StringPair
+import pl.treksoft.kvision.core.Widget
+
+/**
+ * Helper class for maximize icon component.
+ */
+open class MaximizeIcon : Widget(setOf()) {
+
+ override fun render(): VNode {
+ return render("button", arrayOf(KVManager.virtualize("<span aria-hidden='true'>&#x1f5d6;</span>")))
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ cl.add("close" to true)
+ return cl
+ }
+
+ override fun getSnAttrs(): List<StringPair> {
+ return super.getSnAttrs() + listOf("type" to "button", "aria-label" to "Maximize")
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt
new file mode 100644
index 00000000..c8034d09
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/MinimizeIcon.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.window
+
+import com.github.snabbdom.VNode
+import pl.treksoft.kvision.KVManager
+import pl.treksoft.kvision.core.StringBoolPair
+import pl.treksoft.kvision.core.StringPair
+import pl.treksoft.kvision.core.Widget
+
+/**
+ * Helper class for minimize icon component.
+ */
+open class MinimizeIcon : Widget(setOf()) {
+
+ override fun render(): VNode {
+ return render("button", arrayOf(KVManager.virtualize("<span aria-hidden='true'>&#x1f5d5;</span>")))
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ cl.add("close" to true)
+ return cl
+ }
+
+ override fun getSnAttrs(): List<StringPair> {
+ return super.getSnAttrs() + listOf("type" to "button", "aria-label" to "Minimize")
+ }
+}
diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt
new file mode 100644
index 00000000..83473858
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt
@@ -0,0 +1,449 @@
+/*
+ * 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.window
+
+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
+import pl.treksoft.kvision.core.Overflow
+import pl.treksoft.kvision.core.Position
+import pl.treksoft.kvision.core.Resize
+import pl.treksoft.kvision.core.UNIT
+import pl.treksoft.kvision.html.Icon
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+import pl.treksoft.kvision.modal.CloseIcon
+import pl.treksoft.kvision.panel.SimplePanel
+import pl.treksoft.kvision.utils.obj
+import pl.treksoft.kvision.utils.px
+
+internal const val DEFAULT_Z_INDEX = 900
+internal const val WINDOW_HEADER_HEIGHT = 40
+internal const val WINDOW_CONTENT_MARGIN_BOTTOM = 11
+
+/**
+ * Floating window container.
+ *
+ * @constructor
+ * @param caption window title
+ * @param contentWidth window content width
+ * @param contentHeight window content height
+ * @param isResizable determines if the window is resizable
+ * @param isDraggable determines if the window is draggable
+ * @param closeButton determines if Close button is visible
+ * @param maximizeButton determines if Maximize button is visible
+ * @param minimizeButton determines if Minimize button is visible
+ * @param classes a set of CSS class names
+ * @param init an initializer extension function
+ */
+@Suppress("TooManyFunctions")
+open class Window(
+ caption: String? = null,
+ contentWidth: CssSize? = CssSize(0, UNIT.auto),
+ contentHeight: CssSize? = CssSize(0, UNIT.auto),
+ isResizable: Boolean = true,
+ isDraggable: Boolean = true,
+ closeButton: Boolean = false,
+ maximizeButton: Boolean = false,
+ minimizeButton: Boolean = false,
+ icon: String? = null,
+ classes: Set<String> = setOf(),
+ init: (Window.() -> Unit)? = null
+) :
+ SimplePanel(classes + setOf("modal-content", "kv-window")) {
+
+ /**
+ * Window caption text.
+ */
+ var caption
+ get() = captionTag.content
+ set(value) {
+ captionTag.content = value
+ checkHeaderVisibility()
+ }
+ /**
+ * Window content width.
+ */
+ var contentWidth
+ get() = width
+ set(value) {
+ width = value
+ }
+ /**
+ * Window content height.
+ */
+ var contentHeight
+ get() = content.height
+ set(value) {
+ content.height = value
+ }
+ /**
+ * Window content height.
+ */
+ var contentOverflow
+ get() = content.overflow
+ set(value) {
+ content.overflow = value
+ }
+ /**
+ * Determines if the window is resizable.
+ */
+ var isResizable by refreshOnUpdate(isResizable) { checkIsResizable() }
+ /**
+ * Determines if the window is draggable.
+ */
+ var isDraggable by refreshOnUpdate(isDraggable) { checkIsDraggable(); checkHeaderVisibility() }
+ /**
+ * Determines if Close button is visible.
+ */
+ var closeButton
+ get() = closeIcon.visible
+ set(value) {
+ closeIcon.visible = value
+ checkHeaderVisibility()
+ }
+ /**
+ * Determines if Maximize button is visible.
+ */
+ var maximizeButton
+ get() = maximizeIcon.visible
+ set(value) {
+ maximizeIcon.visible = value
+ checkHeaderVisibility()
+ }
+ /**
+ * Determines if Maximize button is visible.
+ */
+ var minimizeButton
+ get() = minimizeIcon.visible
+ set(value) {
+ minimizeIcon.visible = value
+ checkHeaderVisibility()
+ }
+ /**
+ * Window icon.
+ */
+ var icon
+ get() = if (windowIcon.icon == "") null else windowIcon.icon
+ set(value) {
+ windowIcon.icon = value ?: ""
+ windowIcon.visible = (value != null && value != "")
+ }
+
+ private val header = SimplePanel(setOf("modal-header"))
+
+ /**
+ * @suppress
+ * Internal property.
+ */
+ protected val content = SimplePanel().apply {
+ this.height = contentHeight
+ this.overflow = Overflow.AUTO
+ }
+ private val closeIcon = CloseIcon()
+ private val maximizeIcon = MaximizeIcon()
+ private val minimizeIcon = MinimizeIcon()
+ 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 != "")
+ }
+
+ private var isResizeEvent = false
+
+ init {
+ id = "kv_window_$counter"
+ @Suppress("LeakingThis")
+ position = Position.ABSOLUTE
+ @Suppress("LeakingThis")
+ overflow = Overflow.HIDDEN
+ @Suppress("LeakingThis")
+ width = contentWidth
+ @Suppress("LeakingThis")
+ zIndex = ++zIndexCounter
+ header.add(captionTag)
+ captionTag.add(windowIcon)
+ header.add(iconsContainer)
+ minimizeIcon.visible = minimizeButton
+ minimizeIcon.setEventListener {
+ click = { _ ->
+ @Suppress("UnsafeCastFromDynamic")
+ if (this@Window.dispatchEvent("minimizeWindow", obj {}) != false) {
+ toggleMinimize()
+ }
+ }
+ mousedown = { e ->
+ e.stopPropagation()
+ }
+ }
+ iconsContainer.add(minimizeIcon)
+ maximizeIcon.visible = maximizeButton
+ maximizeIcon.setEventListener {
+ click = { _ ->
+ @Suppress("UnsafeCastFromDynamic")
+ if (this@Window.dispatchEvent("maximizeWindow", obj {}) != false) {
+ toggleMaximize()
+ }
+ }
+ mousedown = { e ->
+ e.stopPropagation()
+ }
+ }
+ iconsContainer.add(maximizeIcon)
+ closeIcon.visible = closeButton
+ closeIcon.setEventListener {
+ click = { _ ->
+ @Suppress("UnsafeCastFromDynamic")
+ if (this@Window.dispatchEvent("closeWindow", obj {}) != false) {
+ close()
+ }
+ }
+ mousedown = { e ->
+ e.stopPropagation()
+ }
+ }
+ iconsContainer.add(closeIcon)
+ checkHeaderVisibility()
+ addInternal(header)
+ addInternal(content)
+ checkIsDraggable()
+ if (isResizable) {
+ @Suppress("LeakingThis")
+ resize = Resize.BOTH
+ content.marginBottom = WINDOW_CONTENT_MARGIN_BOTTOM.px
+ }
+ @Suppress("LeakingThis")
+ setEventListener<Window> {
+ click = {
+ toFront()
+ focus()
+ }
+ }
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ counter++
+ }
+
+ private fun checkHeaderVisibility() {
+ @Suppress("ComplexCondition")
+ if (!closeButton && !maximizeButton && !minimizeButton && caption == null && !isDraggable) {
+ header.hide()
+ } else {
+ header.show()
+ }
+ }
+
+ private fun checkIsDraggable() {
+ var isDrag: Boolean
+ if (isDraggable) {
+ header.setEventListener<SimplePanel> {
+ mousedown = { e ->
+ if (e.button.toInt() == 0) {
+ isDrag = true
+ val dragStartX = this@Window.getElementJQuery()?.position()?.left?.toInt() ?: 0
+ val dragStartY = this@Window.getElementJQuery()?.position()?.top?.toInt() ?: 0
+ val dragMouseX = e.pageX
+ val dragMouseY = e.pageY
+ val moveCallback = { me: Event ->
+ if (isDrag) {
+ this@Window.left = (dragStartX + (me as MouseEvent).pageX - dragMouseX).toInt().px
+ this@Window.top = (dragStartY + (me).pageY - dragMouseY).toInt().px
+ }
+ }
+ kotlin.browser.window.addEventListener("mousemove", moveCallback)
+ var upCallback: ((Event) -> Unit)? = null
+ upCallback = {
+ isDrag = false
+ kotlin.browser.window.removeEventListener("mousemove", moveCallback)
+ kotlin.browser.window.removeEventListener("mouseup", upCallback)
+ }
+ kotlin.browser.window.addEventListener("mouseup", upCallback)
+ }
+ }
+ }
+ } else {
+ isDrag = false
+ header.removeEventListeners()
+ }
+ }
+
+ private fun checkIsResizable() {
+ checkResizablEventHandler()
+ if (isResizable) {
+ resize = Resize.BOTH
+ val intHeight = (getElementJQuery()?.height()?.toInt() ?: 0)
+ content.height = (intHeight - WINDOW_HEADER_HEIGHT - WINDOW_CONTENT_MARGIN_BOTTOM).px
+ content.marginBottom = WINDOW_CONTENT_MARGIN_BOTTOM.px
+ } else {
+ resize = Resize.NONE
+ val intHeight = (getElementJQuery()?.height()?.toInt() ?: 0)
+ content.height = (intHeight - WINDOW_HEADER_HEIGHT).px
+ content.marginBottom = 0.px
+ }
+ }
+
+ @Suppress("UnsafeCastFromDynamic")
+ private fun checkResizablEventHandler() {
+ if (isResizable) {
+ if (!isResizeEvent) {
+ isResizeEvent = true
+ KVManagerBootstrap.setResizeEvent(this) {
+ val eid = getElementJQuery()?.attr("id")
+ if (isResizable && eid == id) {
+ val outerWidth = (getElementJQuery()?.outerWidth()?.toInt() ?: 0)
+ val outerHeight = (getElementJQuery()?.outerHeight()?.toInt() ?: 0)
+ val intWidth = (getElementJQuery()?.width()?.toInt() ?: 0)
+ val intHeight = (getElementJQuery()?.height()?.toInt() ?: 0)
+ content.width = intWidth.px
+ content.height = (intHeight - WINDOW_HEADER_HEIGHT - WINDOW_CONTENT_MARGIN_BOTTOM).px
+ width = outerWidth.px
+ height = outerHeight.px
+ this.dispatchEvent("resizeWindow", obj {
+ detail = obj {
+ this.width = outerWidth
+ this.height = outerHeight
+ }
+ })
+ }
+ }
+ }
+ } else if (isResizeEvent) {
+ KVManagerBootstrap.clearResizeEvent(this)
+ isResizeEvent = false
+ }
+ }
+
+ override fun add(child: Component): SimplePanel {
+ content.add(child)
+ return this
+ }
+
+ override fun addAll(children: List<Component>): SimplePanel {
+ content.addAll(children)
+ return this
+ }
+
+ override fun remove(child: Component): SimplePanel {
+ content.remove(child)
+ return this
+ }
+
+ override fun removeAll(): SimplePanel {
+ content.removeAll()
+ return this
+ }
+
+ override fun getChildren(): List<Component> {
+ return content.getChildren()
+ }
+
+ override fun afterCreate(node: VNode) {
+ checkResizablEventHandler()
+ }
+
+ override fun afterDestroy() {
+ if (isResizeEvent) {
+ KVManagerBootstrap.clearResizeEvent(this)
+ isResizeEvent = false
+ }
+ }
+
+ /**
+ * Moves the current window to the front.
+ */
+ open fun toFront() {
+ if ((zIndex ?: 0) < zIndexCounter) zIndex = ++zIndexCounter
+ }
+
+ /**
+ * Makes the current window focused.
+ */
+ open fun focus() {
+ getElementJQuery()?.focus()
+ }
+
+ /**
+ * Close the window.
+ */
+ open fun close() {
+ hide()
+ }
+
+ /**
+ * Maximize or restore the window size.
+ */
+ open fun toggleMaximize() {
+ }
+
+ /**
+ * Minimize or restore the window size.
+ */
+ open fun toggleMinimize() {
+ }
+
+ companion object {
+ internal var counter = 0
+ internal var zIndexCounter = DEFAULT_Z_INDEX
+
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Container.window(
+ caption: String? = null,
+ contentWidth: CssSize? = CssSize(0, UNIT.auto),
+ contentHeight: CssSize? = CssSize(0, UNIT.auto),
+ isResizable: Boolean = true,
+ isDraggable: Boolean = true,
+ closeButton: Boolean = false,
+ maximizeButton: Boolean = false,
+ minimizeButton: Boolean = false,
+ icon: String? = null,
+ classes: Set<String> = setOf(),
+ init: (Window.() -> Unit)? = null
+ ): Window {
+ val window =
+ Window(
+ caption,
+ contentWidth,
+ contentHeight,
+ isResizable,
+ isDraggable,
+ closeButton,
+ maximizeButton,
+ minimizeButton,
+ icon,
+ classes,
+ init
+ )
+ this.add(window)
+ return window
+ }
+ }
+}
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/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..35172267
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/ContextMenuSpec.kt
@@ -0,0 +1,75 @@
+/*
+ * 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 test.pl.treksoft.kvision.dropdown
+
+import pl.treksoft.kvision.dropdown.ContextMenu
+import pl.treksoft.kvision.html.Link.Companion.link
+import pl.treksoft.kvision.panel.Root
+import pl.treksoft.kvision.utils.obj
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class ContextMenuSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val m = ContextMenu {
+ link("a", "b")
+ link("c", "d")
+ }
+ root.setContextMenu(m)
+ m.show()
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<ul class=\"dropdown-menu\" style=\"display: block;\"><li><a href=\"b\">a</a></li><li><a href=\"d\">c</a></li></ul>",
+ element?.innerHTML,
+ "Should render correct context menu"
+ )
+ }
+ }
+
+ @Suppress("UnsafeCastFromDynamic")
+ @Test
+ fun positionMenu() {
+ run {
+ val root = Root("test", fixed = true)
+ val m = ContextMenu {
+ link("a", "b")
+ link("c", "d")
+ }
+ root.setContextMenu(m)
+ m.positionMenu(obj {
+ pageX = 40
+ pageY = 50
+ })
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<ul class=\"dropdown-menu\" style=\"display: block; top: 50px; left: 40px;\"><li><a href=\"b\">a</a></li><li><a href=\"d\">c</a></li></ul>",
+ element?.innerHTML,
+ "Should place context menu in the correct position"
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..e75baf9e
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/HeaderSpec.kt
@@ -0,0 +1,46 @@
+/*
+ * 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 test.pl.treksoft.kvision.dropdown
+
+import pl.treksoft.kvision.dropdown.Header
+import pl.treksoft.kvision.panel.Root
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class HeaderSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val h = Header("Test")
+ root.add(h)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<li class=\"dropdown-header\">Test</li>",
+ element?.innerHTML,
+ "Should render correct drop down header"
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..86607ec7
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/dropdown/SeparatorSpec.kt
@@ -0,0 +1,46 @@
+/*
+ * 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 test.pl.treksoft.kvision.dropdown
+
+import pl.treksoft.kvision.dropdown.Separator
+import pl.treksoft.kvision.panel.Root
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class SeparatorSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val s = Separator()
+ root.add(s)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<li class=\"divider\" role=\"separator\"></li>",
+ element?.innerHTML,
+ "Should render correct drop down separator"
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..40720bcb
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavFormSpec.kt
@@ -0,0 +1,54 @@
+/*
+ * 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 test.pl.treksoft.kvision.navbar
+
+import pl.treksoft.kvision.navbar.NavForm
+import pl.treksoft.kvision.panel.Root
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class NavFormSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val navf = NavForm()
+ root.add(navf)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<form class=\"navbar-form navbar-left\"></form>",
+ element?.innerHTML,
+ "Should render correct nav form"
+ )
+ navf.rightAlign = true
+ assertEqualsHtml(
+ "<form class=\"navbar-form navbar-right\"></form>",
+ element?.innerHTML,
+ "Should render correct right aligned nav form"
+ )
+
+ }
+ }
+
+}
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..988a706d
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavSpec.kt
@@ -0,0 +1,54 @@
+/*
+ * 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 test.pl.treksoft.kvision.navbar
+
+import pl.treksoft.kvision.navbar.Nav
+import pl.treksoft.kvision.panel.Root
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class NavSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val nav = Nav()
+ root.add(nav)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<ul class=\"nav navbar-nav\"></ul>",
+ element?.innerHTML,
+ "Should render correct nav"
+ )
+ nav.rightAlign = true
+ assertEqualsHtml(
+ "<ul class=\"nav navbar-nav navbar-right\"></ul>",
+ element?.innerHTML,
+ "Should render correct right aligned nav"
+ )
+
+ }
+ }
+
+}
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..f38a05f9
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/navbar/NavbarSpec.kt
@@ -0,0 +1,70 @@
+/*
+ * 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 test.pl.treksoft.kvision.navbar
+
+import pl.treksoft.kvision.html.Link.Companion.link
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag.Companion.tag
+import pl.treksoft.kvision.navbar.Nav
+import pl.treksoft.kvision.navbar.Navbar
+import pl.treksoft.kvision.navbar.NavbarType
+import pl.treksoft.kvision.panel.Root
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class NavbarSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val navbar = Navbar("TEST", NavbarType.FIXEDTOP)
+ root.add(navbar)
+ val element = document.getElementById("test")
+ val id = navbar.container.id
+ assertEqualsHtml(
+ "<nav class=\"navbar navbar-fixed-top navbar-default\"><div class=\"container-fluid\"><div class=\"navbar-header\"><button class=\"navbar-toggle collapsed\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$id\" aria-expanded=\"false\"><span class=\"sr-only\">Toggle navigation</span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span></button><a class=\"navbar-brand\" href=\"#\">TEST</a></div><div class=\"collapse navbar-collapse\" id=\"$id\"></div></div></nav>",
+ element?.innerHTML,
+ "Should render correct navbar"
+ )
+ navbar.inverted = true
+ assertEqualsHtml(
+ "<nav class=\"navbar navbar-fixed-top navbar-inverse\"><div class=\"container-fluid\"><div class=\"navbar-header\"><button class=\"navbar-toggle collapsed\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$id\" aria-expanded=\"false\"><span class=\"sr-only\">Toggle navigation</span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span></button><a class=\"navbar-brand\" href=\"#\">TEST</a></div><div class=\"collapse navbar-collapse\" id=\"$id\"></div></div></nav>",
+ element?.innerHTML,
+ "Should render correct inverted navbar"
+ )
+ navbar.add(Nav {
+ tag(TAG.LI) {
+ link("Test", "#!/test")
+ }
+ })
+ assertEqualsHtml(
+ "<nav class=\"navbar navbar-fixed-top navbar-inverse\"><div class=\"container-fluid\"><div class=\"navbar-header\"><button class=\"navbar-toggle collapsed\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$id\" aria-expanded=\"false\"><span class=\"sr-only\">Toggle navigation</span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span><span class=\"icon-bar\"></span></button><a class=\"navbar-brand\" href=\"#\">TEST</a></div><div class=\"collapse navbar-collapse\" id=\"$id\"><ul class=\"nav navbar-nav\"><li><a href=\"#!/test\">Test</a></li></ul></div></div></nav>",
+ element?.innerHTML,
+ "Should render correct navbar with nav link"
+ )
+
+ }
+ }
+
+}
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..fcdf9860
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/ResponsiveGridPanelSpec.kt
@@ -0,0 +1,50 @@
+/*
+ * 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 test.pl.treksoft.kvision.panel
+
+import pl.treksoft.kvision.html.Span
+import pl.treksoft.kvision.panel.ResponsiveGridPanel
+import pl.treksoft.kvision.panel.Root
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class ResponsiveGridPanelSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val rgPanel = ResponsiveGridPanel()
+ root.add(rgPanel)
+ rgPanel.add(Span("abc"), 1, 1)
+ rgPanel.add(Span("def"), 2, 2)
+ rgPanel.add(Span("ghi"), 3, 3)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<div class=\"container-fluid\"><div class=\"row\"></div><div class=\"row\"><div class=\"col-md-3\"></div><div class=\"col-md-3\"><span>abc</span></div><div class=\"col-md-3\"></div><div class=\"col-md-3\"></div></div><div class=\"row\"><div class=\"col-md-3\"></div><div class=\"col-md-3\"></div><div class=\"col-md-3\"><span>def</span></div><div class=\"col-md-3\"></div></div><div class=\"row\"><div class=\"col-md-3\"></div><div class=\"col-md-3\"></div><div class=\"col-md-3\"></div><div class=\"col-md-3\"><span>ghi</span></div></div></div>",
+ element?.innerHTML,
+ "Should render correct responsive grid panel"
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..9335562f
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/panel/TabPanelSpec.kt
@@ -0,0 +1,117 @@
+/*
+ * 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 test.pl.treksoft.kvision.panel
+
+import pl.treksoft.jquery.jQuery
+import pl.treksoft.kvision.html.Span
+import pl.treksoft.kvision.panel.Root
+import pl.treksoft.kvision.panel.TabPanel
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class TabPanelSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val tabs = TabPanel()
+ root.add(tabs)
+ val label1 = Span("abc")
+ val label2 = Span("def")
+ tabs.addTab("ABC", label1)
+ tabs.addTab("DEF", label2)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<div><ul class=\"nav nav-tabs\"><li role=\"presentation\" class=\"active\"><a href=\"#\">ABC</a></li><li role=\"presentation\"><a href=\"#\">DEF</a></li></ul><div><span>abc</span></div></div>",
+ element?.innerHTML,
+ "Should render correct tabs"
+ )
+ }
+ }
+
+ @Test
+ fun setActiveIndex() {
+ run {
+ val root = Root("test", fixed = true)
+ val tabs = TabPanel()
+ root.add(tabs)
+ val label1 = Span("abc")
+ val label2 = Span("def")
+ tabs.addTab("ABC", label1)
+ tabs.addTab("DEF", label2)
+ tabs.activeIndex = 1
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<div><ul class=\"nav nav-tabs\"><li role=\"presentation\" class=\"\"><a href=\"#\">ABC</a></li><li role=\"presentation\" class=\"active\"><a href=\"#\">DEF</a></li></ul><div><span>def</span></div></div>",
+ element?.innerHTML,
+ "Should change selected tab"
+ )
+ }
+ }
+
+ @Test
+ fun removeTab() {
+ run {
+ val root = Root("test", fixed = true)
+ val tabs = TabPanel()
+ root.add(tabs)
+ val label1 = Span("abc")
+ val label2 = Span("def")
+ tabs.addTab("ABC", label1)
+ tabs.addTab("DEF", label2)
+ tabs.activeIndex = 1
+ tabs.removeTab(1)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<div><ul class=\"nav nav-tabs\"><li role=\"presentation\" class=\"\"><a href=\"#\">ABC</a></li></ul><div><span>abc</span></div></div>",
+ element?.innerHTML,
+ "Should remove tab"
+ )
+ }
+ }
+
+
+ @Test
+ fun tabClick() {
+ run {
+ val root = Root("test", fixed = true)
+ val tabs = TabPanel()
+ root.add(tabs)
+ val label1 = Span("abc")
+ val label2 = Span("def")
+ tabs.addTab("ABC", label1)
+ tabs.addTab("DEF", label2)
+ tabs.removeTab(0)
+ val label3 = Span("ghi")
+ tabs.addTab("GHI", label3)
+ jQuery("#test a")[0]?.click()
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<div><ul class=\"nav nav-tabs\"><li role=\"presentation\"><a href=\"#\">DEF</a></li><li role=\"presentation\"><a href=\"#\">GHI</a></li></ul><div><span>def</span></div></div>",
+ element?.innerHTML,
+ "Should select correct tab by clicking"
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..2f044987
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressBarSpec.kt
@@ -0,0 +1,56 @@
+/*
+ * 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 test.pl.treksoft.kvision.progress
+
+import pl.treksoft.kvision.panel.Root
+import pl.treksoft.kvision.progress.ProgressBar
+import pl.treksoft.kvision.progress.ProgressBarStyle
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class ProgressBarSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val progressBar =
+ ProgressBar(50, style = ProgressBarStyle.SUCCESS, striped = true, content = "Processing ...")
+ root.add(progressBar)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<div class=\"progress\"><div class=\"progress-bar progress-bar-success progress-bar-striped\" role=\"progressbar\" aria-valuenow=\"50\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 50%;\">Processing ...</div></div>",
+ element?.innerHTML,
+ "Should render correct progress bar"
+ )
+ progressBar.max = 200
+ assertEqualsHtml(
+ "<div class=\"progress\"><div class=\"progress-bar progress-bar-success progress-bar-striped\" role=\"progressbar\" aria-valuenow=\"50\" aria-valuemin=\"0\" aria-valuemax=\"200\" style=\"width: 25%;\">Processing ...</div></div>",
+ element?.innerHTML,
+ "Should render correct progress bar after max value change"
+ )
+
+ }
+ }
+
+}
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..4aa14230
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/progress/ProgressIndicatorSpec.kt
@@ -0,0 +1,55 @@
+/*
+ * 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 test.pl.treksoft.kvision.progress
+
+import pl.treksoft.kvision.panel.Root
+import pl.treksoft.kvision.progress.ProgressBarStyle
+import pl.treksoft.kvision.progress.ProgressIndicator
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class ProgressIndicatorSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val ind = ProgressIndicator(50, style = ProgressBarStyle.SUCCESS, striped = true)
+ root.add(ind)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<div class=\"progress-bar progress-bar-success progress-bar-striped\" role=\"progressbar\" aria-valuenow=\"50\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width: 50%;\"></div>",
+ element?.innerHTML,
+ "Should render correct progress bar indicator"
+ )
+ ind.max = 200
+ assertEqualsHtml(
+ "<div class=\"progress-bar progress-bar-success progress-bar-striped\" role=\"progressbar\" aria-valuenow=\"50\" aria-valuemin=\"0\" aria-valuemax=\"200\" style=\"width: 25%;\"></div>",
+ element?.innerHTML,
+ "Should render correct progress bar indicator after max value change"
+ )
+
+ }
+ }
+
+}
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..b324b8ab
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ButtonGroupSpec.kt
@@ -0,0 +1,57 @@
+/*
+ * 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 test.pl.treksoft.kvision.toolbar
+
+import pl.treksoft.kvision.panel.Root
+import pl.treksoft.kvision.toolbar.ButtonGroup
+import pl.treksoft.kvision.toolbar.ButtonGroupSize
+import pl.treksoft.kvision.toolbar.ButtonGroupStyle
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class ButtonGroupSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val group = ButtonGroup()
+ root.add(group)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<div class=\"btn-group\" role=\"group\"></div>",
+ element?.innerHTML,
+ "Should render correct button group"
+ )
+ group.size = ButtonGroupSize.LARGE
+ group.style = ButtonGroupStyle.JUSTIFIED
+ assertEqualsHtml(
+ "<div class=\"btn-group btn-group-lg btn-group-justified\" role=\"group\"></div>",
+ element?.innerHTML,
+ "Should render correct button group with large and justified buttons"
+ )
+
+ }
+ }
+
+}
diff --git a/kvision-modules/kvision-bootstrap/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
new file mode 100644
index 00000000..d41ef05e
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap/src/test/kotlin/test/pl/treksoft/kvision/toolbar/ToolbarSpec.kt
@@ -0,0 +1,47 @@
+/*
+ * 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 test.pl.treksoft.kvision.toolbar
+
+import pl.treksoft.kvision.panel.Root
+import pl.treksoft.kvision.toolbar.Toolbar
+import test.pl.treksoft.kvision.DomSpec
+import kotlin.browser.document
+import kotlin.test.Test
+
+class ToolbarSpec : DomSpec {
+
+ @Test
+ fun render() {
+ run {
+ val root = Root("test", fixed = true)
+ val toolbar = Toolbar()
+ root.add(toolbar)
+ val element = document.getElementById("test")
+ assertEqualsHtml(
+ "<div class=\"btn-toolbar\" role=\"toolbar\"></div>",
+ element?.innerHTML,
+ "Should render correct toolbar"
+ )
+ }
+ }
+
+}
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() {}
}