diff options
| author | Robert Jaros <rjaros@finn.pl> | 2020-06-06 23:59:31 +0200 |
|---|---|---|
| committer | Robert Jaros <rjaros@finn.pl> | 2020-06-06 23:59:31 +0200 |
| commit | 2993527f8297169ce91826a91bfcf168e79ccc88 (patch) | |
| tree | b13a5b677a631fa9bf3921bb26701a69716dfd39 /kvision-modules | |
| parent | dd41d887f679b3bb92e75845270d9981f7443ee9 (diff) | |
| download | kvision-2993527f8297169ce91826a91bfcf168e79ccc88.tar.gz kvision-2993527f8297169ce91826a91bfcf168e79ccc88.tar.bz2 kvision-2993527f8297169ce91826a91bfcf168e79ccc88.zip | |
New kvision-onsenui modules. Support for main structural components of OnsenUI with DSL builders. Work in progress. (#126)
Diffstat (limited to 'kvision-modules')
23 files changed, 2857 insertions, 0 deletions
diff --git a/kvision-modules/kvision-onsenui-css/build.gradle.kts b/kvision-modules/kvision-onsenui-css/build.gradle.kts new file mode 100644 index 00000000..04ca8d8b --- /dev/null +++ b/kvision-modules/kvision-onsenui-css/build.gradle.kts @@ -0,0 +1,48 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("onsenui", "^2.10.10")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") { + filter { it.replace("\"main\": \"kotlin/kvision-kvision", "\"main\": \"kvision-kvision") } + } + } +} diff --git a/kvision-modules/kvision-onsenui-css/src/main/kotlin/pl/treksoft/kvision/KVManagerOnsenuiCss.kt b/kvision-modules/kvision-onsenui-css/src/main/kotlin/pl/treksoft/kvision/KVManagerOnsenuiCss.kt new file mode 100644 index 00000000..160b48e0 --- /dev/null +++ b/kvision-modules/kvision-onsenui-css/src/main/kotlin/pl/treksoft/kvision/KVManagerOnsenuiCss.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017-present Robert Jaros + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package pl.treksoft.kvision + +internal val kVManagerOnsenuiCssInit = KVManagerOnsenuiCss.init() + +/** + * Internal singleton object which initializes and configures KVision OnsenUI CSS module. + */ +internal object KVManagerOnsenuiCss { + init { + require("onsenui/css/ionicons/css/ionicons.min.css") + require("onsenui/css/material-design-iconic-font/css/material-design-iconic-font.min.css") + require("onsenui/css/onsenui-core.min.css") + require("onsenui/css/onsen-css-components.min.css") + } + + internal fun init() {} +} diff --git a/kvision-modules/kvision-onsenui-css/webpack.config.d/css.js b/kvision-modules/kvision-onsenui-css/webpack.config.d/css.js new file mode 100644 index 00000000..5d710d35 --- /dev/null +++ b/kvision-modules/kvision-onsenui-css/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-onsenui-css/webpack.config.d/file.js b/kvision-modules/kvision-onsenui-css/webpack.config.d/file.js new file mode 100644 index 00000000..653ca21f --- /dev/null +++ b/kvision-modules/kvision-onsenui-css/webpack.config.d/file.js @@ -0,0 +1,9 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + loader: 'file-loader', + options: { + esModule: false, + }, + } +); diff --git a/kvision-modules/kvision-onsenui-css/webpack.config.d/fonts.js b/kvision-modules/kvision-onsenui-css/webpack.config.d/fonts.js new file mode 100644 index 00000000..35b28e6a --- /dev/null +++ b/kvision-modules/kvision-onsenui-css/webpack.config.d/fonts.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader'}); diff --git a/kvision-modules/kvision-onsenui/build.gradle.kts b/kvision-modules/kvision-onsenui/build.gradle.kts new file mode 100644 index 00000000..04ca8d8b --- /dev/null +++ b/kvision-modules/kvision-onsenui/build.gradle.kts @@ -0,0 +1,48 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("js") + id("maven-publish") +} + +repositories() + +kotlin { + kotlinJsTargets() +} + +dependencies { + implementation(kotlin("stdlib-js")) + api(rootProject) + implementation(npm("onsenui", "^2.10.10")) + testImplementation(kotlin("test-js")) +} + +val sourcesJar by tasks.registering(Jar::class) { + archiveClassifier.set("sources") + from(kotlin.sourceSets.main.get().kotlin) +} + +publishing { + publications { + create<MavenPublication>("kotlin") { + from(components["kotlin"]) + artifact(tasks["sourcesJar"]) + pom { + defaultPom() + } + } + } +} + +setupPublication() + +tasks { + getByName("JsJar", Jar::class) { + from("${rootProject.buildDir}/js/packages/kvision-${project.name}/package.json") { + filter { it.replace("\"main\": \"kotlin/kvision-kvision", "\"main\": \"kvision-kvision") } + } + } +} diff --git a/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/KVManagerOnsenui.kt b/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/KVManagerOnsenui.kt new file mode 100644 index 00000000..d0d184ab --- /dev/null +++ b/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/KVManagerOnsenui.kt @@ -0,0 +1,34 @@ +/* + * 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 kVManagerOnsenuiInit = KVManagerOnsenui.init() + +/** + * Internal singleton object which initializes and configures KVision OnsenUI module. + */ +internal object KVManagerOnsenui { + + internal val ons = require("onsenui/js/onsenui.min.js") + + internal fun init() {} +} diff --git a/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/onsenui/OnsenUi.kt b/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/onsenui/OnsenUi.kt new file mode 100644 index 00000000..9cbc960e --- /dev/null +++ b/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/onsenui/OnsenUi.kt @@ -0,0 +1,359 @@ +/* + * 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.onsenui + +import pl.treksoft.kvision.KVManagerOnsenui.ons + +/** + * Back button event type. + */ +external interface BackButtonEvent { + fun callParentHandler() +} + +/** + * Change orientation event event type. + */ +external interface OrientationEvent { + val isPortrait: Boolean +} + +/** + * Platform types. + */ +enum class Platform(internal val type: String) { + OPERA("opera"), + FIREFOX("firefox"), + SAFARI("safari"), + CHROME("chrome"), + IE("ie"), + EDGE("edge"), + ANDROID("android"), + BLACKBERRY("blackberry"), + IOS("ios"), + WP("wp") +} + +/** + * Contains global Onsen UI functions. + */ +@Suppress("UnsafeCastFromDynamic") +object OnsenUi { + + /** + * Whether OnsenUI engine is loaded and ready. + */ + fun isReady(): Boolean { + return ons.isReady() + } + + /** + * Whether app is running inside Cordova. + */ + fun isWebView(): Boolean { + return ons.isWebView() + } + + /** + * A function called when engine is loaded and ready. + */ + fun ready(callback: () -> Unit) { + ons.ready(callback) + } + + /** + * Set default listener for the device back button event. + */ + fun setDefaultDeviceBackButtonListener(listener: (event: dynamic) -> Unit) { + ons.setDefaultDeviceBackButtonListener(listener) + } + + /** + * Disable default handler for the device back button. + */ + fun disableDeviceBackButtonHandler() { + ons.disableDeviceBackButtonHandler() + } + + /** + * Enable default handler for the device back button. + */ + fun enableDeviceBackButtonHandler() { + ons.enableDeviceBackButtonHandler() + } + + /** + * Enable status bar fill on IOS7 and above (except iPhone X) + */ + fun enableAutoStatusBarFill() { + ons.enableAutoStatusBarFill() + } + + /** + * Disable status bar fill on IOS7 and above (except iPhone X) + */ + fun disableAutoStatusBarFill() { + ons.disableAutoStatusBarFill() + } + + /** + * Creates a static element similar to iOS/Android status bar. + */ + fun mockStatusBar() { + ons.mockStatusBar() + } + + /** + * Disable all animations. + */ + fun disableAnimations() { + ons.disableAnimations() + } + + /** + * Enable all animations. + */ + fun enableAnimations() { + ons.enableAnimations() + } + + /** + * Disable automatic styling. + */ + fun disableAutoStyling() { + ons.disableAutoStyling() + } + + /** + * Enable automatic styling. + */ + fun enableAutoStyling() { + ons.enableAutoStyling() + } + + /** + * Disable adding fa- prefix for icons. + */ + fun disableIconAutoPrefix() { + ons.disableIconAutoPrefix() + } + + /** + * Applies a scroll fix for iOS UIWebView. + */ + fun forceUIWebViewScrollFix(force: Boolean) { + ons.forceUIWebViewScrollFix(force) + } + + /** + * Force styling for the given platform. + */ + fun forcePlatformStyling(platform: Platform) { + ons.forcePlatformStyling(platform.type) + } + + /** + * Set styling for the given platform (preferred) + */ + fun platformSelect(platform: Platform) { + ons.platform.select(platform.type) + } + + /** + * Whether device is iPhone. + * @param forceActualPlatform return the actual platform. + */ + fun isIOS(forceActualPlatform: Boolean = false): Boolean { + return ons.platform.isIOS(forceActualPlatform) + } + + /** + * Whether device is Android. + * @param forceActualPlatform return the actual platform. + */ + fun isAndroid(forceActualPlatform: Boolean = false): Boolean { + return ons.platform.isAndroid(forceActualPlatform) + } + + /** + * Whether device is Android phone. + */ + fun isAndroidPhone(): Boolean { + return ons.platform.isAndroidPhone() + } + + /** + * Whether device is Android tablet. + */ + fun isAndroidTablet(): Boolean { + return ons.platform.isAndroidTablet() + } + + /** + * Whether device is UIWebView. + */ + fun isUIWebView(): Boolean { + return ons.platform.isUIWebView() + } + + /** + * Whether device is iOS Safari. + */ + fun isIOSSafari(): Boolean { + return ons.platform.isIOSSafari() + } + + /** + * Whether device is WKWebView. + */ + fun isWKWebView(): Boolean { + return ons.platform.isWKWebView() + } + + /** + * Whether device is iPhone. + */ + fun isIPhone(): Boolean { + return ons.platform.isIPhone() + } + + /** + * Whether device is iPhone X, XS, XS Max, or XR. + */ + fun isIPhoneX(): Boolean { + return ons.platform.isIPhoneX() + } + + /** + * Whether device is iPad. + */ + fun isIPad(): Boolean { + return ons.platform.isIPad() + } + + /** + * Whether device is BlackBerry. + * @param forceActualPlatform return the actual platform. + */ + fun isBlackBerry(forceActualPlatform: Boolean = false): Boolean { + return ons.platform.isBlackBerry(forceActualPlatform) + } + + /** + * Whether browser is Opera. + * @param forceActualPlatform return the actual platform. + */ + fun isOpera(forceActualPlatform: Boolean = false): Boolean { + return ons.platform.isOpera(forceActualPlatform) + } + + /** + * Whether browser is Firefox. + * @param forceActualPlatform return the actual platform. + */ + fun isFirefox(forceActualPlatform: Boolean = false): Boolean { + return ons.platform.isFirefox(forceActualPlatform) + } + + /** + * Whether browser is Safari. + * @param forceActualPlatform return the actual platform. + */ + fun isSafari(forceActualPlatform: Boolean = false): Boolean { + return ons.platform.isSafari(forceActualPlatform) + } + + /** + * Whether browser is Chrome. + * @param forceActualPlatform return the actual platform. + */ + fun isChrome(forceActualPlatform: Boolean = false): Boolean { + return ons.platform.isChrome(forceActualPlatform) + } + + /** + * Whether browser is IE. + * @param forceActualPlatform return the actual platform. + */ + fun isIE(forceActualPlatform: Boolean = false): Boolean { + return ons.platform.isIE(forceActualPlatform) + } + + /** + * Whether device is iOS 7 or above. + */ + fun isIOS7above(): Boolean { + return ons.platform.isIOS7above() + } + + /** + * Whether browser is Edge. + * @param forceActualPlatform return the actual platform. + */ + fun isEdge(forceActualPlatform: Boolean = false): Boolean { + return ons.platform.isEdge(forceActualPlatform) + } + + /** + * Whether device is Windows Phone. + * @param forceActualPlatform return the actual platform. + */ + fun isWP(forceActualPlatform: Boolean = false): Boolean { + return ons.platform.isWP(forceActualPlatform) + } + + /** + * Function called on orientation change event. + */ + fun onOrientationChange(callback: (OrientationEvent) -> Unit) { + ons.orientation.on("change", callback) + } + + /** + * Function called on a single orientation change event. + */ + fun onOrientationChangeOnce(callback: (OrientationEvent) -> Unit) { + ons.orientation.once("change", callback) + } + + /** + * Remove orientation change event listener/all listeners. + */ + fun offOrientationChange(callback: ((OrientationEvent) -> Unit)? = undefined) { + ons.orientation.off("change", callback) + } + + /** + * Whether orientation is portrait. + */ + fun isPortrait(): Boolean { + return ons.orientation.isPortrait() + } + + /** + * Whether orientation is landscape. + */ + fun isLandscape(): Boolean { + return ons.orientation.isLandscape() + } +} diff --git a/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/onsenui/core/BackButton.kt b/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/onsenui/core/BackButton.kt new file mode 100644 index 00000000..0832e74e --- /dev/null +++ b/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/onsenui/core/BackButton.kt @@ -0,0 +1,115 @@ +/* + * 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.onsenui.core + +import com.github.snabbdom.VNode +import org.w3c.dom.events.MouseEvent +import pl.treksoft.kvision.core.Component +import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.html.Align +import pl.treksoft.kvision.html.Div +import pl.treksoft.kvision.utils.set + +/** + * A back button component designed to be placed inside the toolbar. + * + * @constructor Creates a back button component. + * @param content the content of the button. + * @param rich whether [content] can contain HTML code + * @param align text align + * @param classes a set of CSS class names + * @param init an initializer extension function + */ +@Suppress("LeakingThis") +open class BackButton( + content: String? = null, + rich: Boolean = false, + align: Align? = null, + classes: Set<String> = setOf(), + init: (BackButton.() -> Unit)? = null +) : Div(content, rich, align, classes) { + + /** + * A modifier attribute to specify custom styles. + */ + var modifier: String? by refreshOnUpdate() + + init { + init?.invoke(this) + } + + override fun render(elementName: String, children: Array<dynamic>): VNode { + return super.render("ons-back-button", children) + } + + override fun getSnAttrs(): List<StringPair> { + val sn = super.getSnAttrs().toMutableList() + modifier?.let { + sn.add("modifier" to it) + } + return sn + } + + override fun afterInsert(node: VNode) { + getElement()?.asDynamic()?.onClick = { + var component: Component? = this + while (component != null) { + component = component.parent + if (component is Navigator) { + component.popPage() + break + } + } + } + } + + /** + * A convenient helper for easy setting onClick event handler. + */ + open fun onClick(handler: BackButton.(MouseEvent) -> Unit): BackButton { + this.setEventListener<BackButton> { + click = { e -> + self.handler(e) + } + } + return this + } +} + +/** + * DSL builder extension function. + * + * It takes the same parameters as the constructor of the built component. + */ +fun Div.backButton( + content: String? = null, + rich: Boolean = false, + align: Align? = null, + classes: Set<String>? = null, + className: String? = null, + init: (BackButton.() -> Unit)? = null +): BackButton { + val backButton = BackButton(content, rich, align, classes ?: className.set, init) + this.add(backButton) + return backButton +} diff --git a/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/onsenui/core/Navigator.kt b/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/onsenui/core/Navigator.kt new file mode 100644 index 00000000..fdd7ad8c --- /dev/null +++ b/kvision-modules/kvision-onsenui/src/main/kotlin/pl/treksoft/kvision/onsenui/core/Navigator.kt @@ -0,0 +1,421 @@ +/* + * 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.onsenui.core + +import com.github.snabbdom.VNode +import pl.treksoft.kvision.KVManagerOnsenui.ons +import pl.treksoft.kvision.core.Display +import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.onsenui.BackButtonEvent +import pl.treksoft.kvision.onsenui.splitter.SplitterContent +import pl.treksoft.kvision.onsenui.tabbar.Tab +import pl.treksoft.kvision.panel.Root +import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.createInstance +import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set +import kotlin.js.Promise + +/** + * Navigator animation types. + */ +enum class NavAnimation(internal val type: String) { + NONE("none"), + FADE("fade"), + LIFT("lift"), + SLIDE("slide"), + FADEMD("fade-md"), + LIFTMD("lift-md"), + SLIDEMD("slide-md"), + FADEIOS("fade-ios"), + LIFTIOS("lift-ios"), + SLIDEIOS("slide-ios") +} + +/** + * A navigator component. + * + * @constructor Creates a navigator component. + * @param animation an animation type. + * @param swipeable an iOS swipe to pop feature + * @param classes a set of CSS class names + * @param init an initializer extension function + */ +open class Navigator( + animation: NavAnimation? = null, + swipeable: Boolean? = null, + classes: Set<String> = setOf(), + init: (Navigator.() -> Unit)? = null +) : SimplePanel(classes) { + + /** + * An animation type. + */ + var animation: NavAnimation? by refreshOnUpdate(animation) + + /** + * An iOS swipe to pop feature. + */ + var swipeable: Boolean? by refreshOnUpdate(swipeable) + + /** + * The width of swipeable area calculated from the edge (in pixels). + */ + var swipeTargetWidth: Number? by refreshOnUpdate() + + /** + * Specify how much the page needs to be swiped before popping. + */ + var swipeThreshold: Number? by refreshOnUpdate() + + /** + * Device back button event listener function. + */ + protected var onDeviceBackButtonCallback: ((BackButtonEvent) -> Unit)? = null + + /** + * Swipe event listener function. + */ + protected var onSwipeCallback: ((Number) -> Unit)? = null + + internal val pagesMap = mutableMapOf<String, Page>() + + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + + /** + * A dynamic property returning current top page. + */ + val topPage: dynamic + get() = getElement()?.asDynamic()?.topPage + + /** + * A dynamic property returning current pages stack. + */ + val pages: dynamic + get() = getElement()?.asDynamic()?.pages + + override fun render(): VNode { + return render("ons-navigator", childrenVNodes()) + } + + override fun getSnAttrs(): List<StringPair> { + val sn = super.getSnAttrs().toMutableList() + animation?.let { + sn.add("animation" to it.type) + } + if (swipeable == true) { + sn.add("swipeable" to "swipeable") + } + swipeTargetWidth?.let { + sn.add("swipe-target-width" to "${it}px") + } + swipeThreshold?.let { + sn.add("swipe-threshold" to it.toString()) + } + return sn + } + + @Suppress("UnsafeCastFromDynamic") + override fun afterInsert(node: VNode) { + node.elm.asDynamic().pageLoader = (ons.PageLoader as Any).createInstance<Any& |
