diff options
author | Robert Jaros <rjaros@finn.pl> | 2019-10-03 19:03:21 +0200 |
---|---|---|
committer | Robert Jaros <rjaros@finn.pl> | 2019-10-03 19:03:21 +0200 |
commit | 6b53324c97bfc80ed14dfca6a5dbc879950715b9 (patch) | |
tree | 55c7bb7d06e37470795a93e1f542e51ef3f1ace6 /kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar | |
parent | 22a8d5c35db97d65a90b21d97e6835380191845d (diff) | |
download | kvision-6b53324c97bfc80ed14dfca6a5dbc879950715b9.tar.gz kvision-6b53324c97bfc80ed14dfca6a5dbc879950715b9.tar.bz2 kvision-6b53324c97bfc80ed14dfca6a5dbc879950715b9.zip |
Upgrade to Bootstrap 4.
Upgrade to Font Awesome 5.
Restructure modules.
Diffstat (limited to 'kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar')
3 files changed, 411 insertions, 0 deletions
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 + ) + } +} |