aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt
diff options
context:
space:
mode:
authorRobert Jaros <rjaros@finn.pl>2019-10-07 09:58:14 +0200
committerRobert Jaros <rjaros@finn.pl>2019-10-07 09:58:14 +0200
commit04ac8542c218b7ce5199350f0880e8f7cb4252b6 (patch)
tree4f96d1c3bb8281289b96e2b11eecc404a3c98788 /src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt
parent6678eec9799681b09e5ac85de1a39596d56de22f (diff)
parent6b14906f0e35dc522bd1c1a44682d728315cf619 (diff)
downloadkvision-04ac8542c218b7ce5199350f0880e8f7cb4252b6.tar.gz
kvision-04ac8542c218b7ce5199350f0880e8f7cb4252b6.tar.bz2
kvision-04ac8542c218b7ce5199350f0880e8f7cb4252b6.zip
Merge branch 'bs4'
Diffstat (limited to 'src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt')
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt270
1 files changed, 0 insertions, 270 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt
deleted file mode 100644
index f620f2b0..00000000
--- a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * 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.children.forEach {
- it.removeCssClass("active")
- }
- if (content.activeIndex in nav.children.indices) {
- nav.children[content.activeIndex].addCssClass("active")
- }
- }
- }
- private val navClasses = when (tabPosition) {
- TabPosition.TOP -> if (scrollableTabs) setOf("nav", "nav-tabs", "tabs-top") else setOf("nav", "nav-tabs")
- TabPosition.LEFT -> setOf("nav", "nav-tabs", "tabs-left")
- TabPosition.RIGHT -> setOf("nav", "nav-tabs", "tabs-right")
- }
- 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.addCssClass("clearfix")
- val sizes = calculateSideClasses()
- this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "col-nopadding")))
- this.addInternal(WidgetWrapper(content, setOf(sizes.second, "col-nopadding")))
- }
- TabPosition.RIGHT -> {
- this.addCssClass("clearfix")
- val sizes = calculateSideClasses()
- this.addInternal(WidgetWrapper(content, setOf(sizes.second, "col-nopadding")))
- this.addInternal(WidgetWrapper(nav, setOf(sizes.first, "col-nopadding")))
- }
- }
- @Suppress("LeakingThis")
- init?.invoke(this)
- }
-
- private fun calculateSideClasses(): Pair<String, String> {
- return when (sideTabSize) {
- SideTabSize.SIZE_1 -> Pair("col-xs-1", "col-xs-11")
- SideTabSize.SIZE_2 -> Pair("col-xs-2", "col-xs-10")
- SideTabSize.SIZE_3 -> Pair("col-xs-3", "col-xs-9")
- SideTabSize.SIZE_4 -> Pair("col-xs-4", "col-xs-8")
- SideTabSize.SIZE_5 -> Pair("col-xs-5", "col-xs-7")
- SideTabSize.SIZE_6 -> Pair("col-xs-6", "col-xs-6")
- }
- }
-
- /**
- * 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) {
- role = "presentation"
- link(title, "#", icon, image) {
- if (closable) {
- cicon("remove") {
- addCssClass("kv-tab-close")
- setEventListener<Icon> {
- click = { e ->
- val actIndex = this@TabPanel.content.children.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.children.indexOf(childrenMap[currentIndex])
- e.preventDefault()
- if (route != null) {
- routing.navigate(route)
- }
- }
- }
- }
- nav.add(tag)
- if (nav.children.size == 1) {
- tag.addCssClass("active")
- activeIndex = 0
- }
- content.add(panel)
- if (route != null) {
- routing.on(route, { _ -> activeIndex = this@TabPanel.content.children.indexOf(childrenMap[currentIndex]) })
- .resolve()
- }
- return this
- }
-
- /**
- * Removes tab at given index.
- */
- open fun removeTab(index: Int): TabPanel {
- nav.remove(nav.children[index])
- childrenMap.filter { it.value == content.children[index] }.keys.firstOrNull()?.let {
- childrenMap.remove(it)
- }
- content.remove(content.children[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.children.indexOf(child)
- return removeTab(index)
- }
-
- /**
- * Returns child component by tab index.
- * @param index tab index
- */
- open fun getChildComponent(index: Int): Component? {
- return content.children[index]
- }
-
- /**
- * Returns tab header component by tab index.
- * @param index tab index
- */
- open fun getNavComponent(index: Int): Tag? {
- return nav.children[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
- }
- }
-}