diff options
Diffstat (limited to 'src/main')
74 files changed, 0 insertions, 11006 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt deleted file mode 100644 index 0030cf9d..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt +++ /dev/null @@ -1,157 +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 - -import com.github.snabbdom.Snabbdom -import com.github.snabbdom.VNode -import com.github.snabbdom.attributesModule -import com.github.snabbdom.classModule -import com.github.snabbdom.datasetModule -import com.github.snabbdom.eventListenersModule -import com.github.snabbdom.propsModule -import com.github.snabbdom.styleModule -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.utils.isIE11 -import kotlin.browser.document -import kotlin.dom.clear - -/** - * @suppress - * External function for loading CommonJS modules. - */ -external fun require(name: String): dynamic - -/** - * Internal singleton object which initializes and configures KVision framework. - */ -@Suppress("EmptyCatchBlock") -internal object KVManager { - internal const val AJAX_REQUEST_DELAY = 300 - internal const val KVNULL = "#kvnull" - - private val bootstrapWebpack = try { - require("bootstrap-webpack") - } catch (e: Throwable) { - } - private val fontAwesomeWebpack = try { - require("font-awesome-webpack") - } catch (e: Throwable) { - } - private val awesomeBootstrapCheckbox = try { - require("awesome-bootstrap-checkbox") - } catch (e: Throwable) { - } - private val bootstrapSelectCss = try { - 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") - } catch (e: Throwable) { - } - private val bootstrapSelectI18n = try { - require("./js/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") - } catch (e: Throwable) { - } - private val trixCss = try { - require("trix/dist/trix.css") - } catch (e: Throwable) { - } - private val trix = try { - require("trix") - } catch (e: Throwable) { - } - private val bootstrapDateTimePickerCss = try { - 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") - } catch (e: Throwable) { - } - private val bootstrapTouchspinCss = try { - 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) { - } - private val elementResizeEvent = try { - require("element-resize-event") - } catch (e: Throwable) { - } - - private val resizable = require("jquery-resizable-dom") - internal val fecha = require("fecha") - private val sdPatch = Snabbdom.init( - arrayOf( - classModule, attributesModule, propsModule, styleModule, - eventListenersModule, datasetModule - ) - ) - private val sdVirtualize = require("snabbdom-virtualize/strings").default - private val styleCss = require("./css/style.css") - - internal fun patch(id: String, vnode: VNode): VNode { - val container = document.getElementById(id) - container?.clear() - return sdPatch(container, vnode) - } - - internal fun patch(oldVNode: VNode, newVNode: VNode): VNode { - return sdPatch(oldVNode, newVNode) - } - - @Suppress("UnsafeCastFromDynamic") - internal fun virtualize(html: String): VNode { - return sdVirtualize(html) - } - - @Suppress("UnsafeCastFromDynamic") - internal fun setResizeEvent(component: Component, callback: () -> Unit) { - if (!isIE11()) { - component.getElement()?.let { - elementResizeEvent(it, callback) - } - } - } - - @Suppress("UnsafeCastFromDynamic") - internal fun clearResizeEvent(component: Component) { - if (!isIE11()) { - if (component.getElement()?.asDynamic()?.__resizeTrigger__?.contentDocument != null) { - component.getElement()?.let { - elementResizeEvent.unbind(it) - } - } - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Component.kt b/src/main/kotlin/pl/treksoft/kvision/core/Component.kt deleted file mode 100644 index 7125536a..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/core/Component.kt +++ /dev/null @@ -1,116 +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.core - -import com.github.snabbdom.VNode -import org.w3c.dom.Node -import pl.treksoft.jquery.JQuery -import pl.treksoft.kvision.panel.Root - -/** - * Base interface for all components. - */ -interface Component { - /** - * Parent of the current component. - */ - var parent: Component? - /** - * Visibility state of the current component. - */ - var visible: Boolean - - /** - * Adds given value to the set of CSS classes generated in html code of current component. - * @param css CSS class name - * @return current component - */ - fun addCssClass(css: String): Component - - /** - * Removes given value from the set of CSS classes generated in html code of current component. - * @param css CSS class name - * @return current component - */ - fun removeCssClass(css: String): Component - - /** - * Adds given value to the set of CSS classes generated in html code of parent component. - * @param css CSS class name - * @return current component - */ - fun addSurroundingCssClass(css: String): Component - - /** - * Removes given value from the set of CSS classes generated in html code of parent component. - * @param css CSS class name - * @return current component - */ - fun removeSurroundingCssClass(css: String): Component - - /** - * @suppress - * Internal function - * Renders current component as a Snabbdom vnode. - * @return Snabbdom vnode - */ - fun renderVNode(): VNode - - /** - * Returns DOM element bound to the current component. - * @return DOM element - */ - fun getElement(): Node? - - /** - * Returns JQuery element bound to the current component. - * @return JQuery element - */ - fun getElementJQuery(): JQuery? - - /** - * Returns JQuery element bound to the current component as a *dynamic* type. - * @return JQuery element as a *dynamic* type - */ - fun getElementJQueryD(): dynamic - - /** - * @suppress - * Internal function. - * Sets **parent** property of current component to null. - * @return current component - */ - fun clearParent(): Component - /** - * @suppress - * Internal function. - * Returns root component - the root node of components tree - * @return root component - */ - fun getRoot(): Root? - /** - * @suppress - * Internal function - * Cleans resources allocated by the current component. - */ - fun dispose() -} diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Container.kt b/src/main/kotlin/pl/treksoft/kvision/core/Container.kt deleted file mode 100644 index 653f4a79..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/core/Container.kt +++ /dev/null @@ -1,69 +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.core - -/** - * Base interface for all containers. - */ -interface Container : Component { - /** - * Adds given component to the current container. - * @param child child component - * @return current container - */ - fun add(child: Component): Container - - /** - * Adds a list of components to the current container. - * @param children list of child components - * @return current container - */ - fun addAll(children: List<Component>): Container - - /** - * Operator function for adding children in a DSL style. - * @param children children components - * @return current container - */ - operator fun invoke(vararg children: Component): Container { - return addAll(children.asList()) - } - - /** - * Removes given component from the current container. - * @param child child component - * @return current container - */ - fun remove(child: Component): Container - - /** - * Removes all children from the current container. - * @return current container - */ - fun removeAll(): Container - - /** - * Returns a list of children of the current container. - * @return list of children - */ - fun getChildren(): List<Component> -} diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Css.kt b/src/main/kotlin/pl/treksoft/kvision/core/Css.kt deleted file mode 100644 index ff01cc9f..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/core/Css.kt +++ /dev/null @@ -1,455 +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.core - -import pl.treksoft.kvision.utils.asString -import pl.treksoft.kvision.utils.toHexString - -/** - * Definitions of CSS units. - */ -@Suppress("EnumNaming", "EnumEntryName") -enum class UNIT(internal val unit: String) { - px("px"), - pt("pt"), - em("em"), - cm("cm"), - mm("mm"), - `in`("in"), - pc("pc"), - ch("ch"), - rem("rem"), - vw("vw"), - vh("vh"), - vmin("vmin"), - vmax("vmax"), - perc("%"), - auto("auto") -} - -/** - * Definitions of CSS border styles. - */ -enum class BorderStyle(internal val borderStyle: String) { - NONE("none"), - HIDDEN("hidden"), - DOTTED("dotted"), - DASHED("dashed"), - SOLID("solid"), - DOUBLE("double"), - GROOVE("groove"), - RIDGE("ridge"), - INSET("inset"), - OUTSET("outset"), - INITIAL("initial"), - INHERIT("inherit") -} - -/** - * Definitions of CSS color names. - */ -enum class Col(internal val color: String) { - ALICEBLUE("aliceblue"), - ANTIQUEWHITE("antiquewhite"), - AQUA("aqua"), - AQUAMARINE("aquamarine"), - AZURE("azure"), - BEIGE("beige"), - BISQUE("bisque"), - BLACK("black"), - BLANCHEDALMOND("blanchedalmond"), - BLUE("blue"), - BLUEVIOLET("blueviolet"), - BROWN("brown"), - BURLYWOOD("burlywood"), - CADETBLUE("cadetblue"), - CHARTREUSE("chartreuse"), - CHOCOLATE("chocolate"), - CORAL("coral"), - CORNFLOWERBLUE("cornflowerblue"), - CORNSILK("cornsilk"), - CRIMSON("crimson"), - CYAN("cyan"), - DARKBLUE("darkblue"), - DARKCYAN("darkcyan"), - DARKGOLDENROD("darkgoldenrod"), - DARKGRAY("darkgray"), - DARKGREEN("darkgreen"), - DARKKHAKI("darkkhaki"), - DARKMAGENTA("darkmagenta"), - DARKOLIVEGREEN("darkolivegreen"), - DARKORANGE("darkorange"), - DARKORCHID("darkorchid"), - DARKRED("darkred"), - DARKSALMON("darksalmon"), - DARKSEAGREEN("darkseagreen"), - DARKSLATEBLUE("darkslateblue"), - DARKSLATEGRAY("darkslategray"), - DARKTURQUOISE("darkturquoise"), - DARKVIOLET("darkviolet"), - DEEPPINK("deeppink"), - DEEPSKYBLUE("deepskyblue"), - DIMGRAY("dimgray"), - DODGERBLUE("dodgerblue"), - FIREBRICK("firebrick"), - FLORALWHITE("floralwhite"), - FORESTGREEN("forestgreen"), - FUCHSIA("fuchsia"), - GAINSBORO("gainsboro"), - GHOSTWHITE("ghostwhite"), - GOLD("gold"), - GOLDENROD("goldenrod"), - GRAY("gray"), - GREEN("green"), - GREENYELLOW("greenyellow"), - HONEYDEW("honeydew"), - HOTPINK("hotpink"), - INDIANRED("indianred"), - INDIGO("indigo"), - IVORY("ivory"), - KHAKI("khaki"), - LAVENDER("lavender"), - LAVENDERBLUSH("lavenderblush"), - LAWNGREEN("lawngreen"), - LEMONCHIFFON("lemonchiffon"), - LIGHTBLUE("lightblue"), - LIGHTCORAL("lightcoral"), - LIGHTCYAN("lightcyan"), - LIGHTGOLDENRODYELLOW("lightgoldenrodyellow"), - LIGHTGRAY("lightgray"), - LIGHTGREEN("lightgreen"), - LIGHTPINK("lightpink"), - LIGHTSALMON("lightsalmon"), - LIGHTSEAGREEN("lightseagreen"), - LIGHTSKYBLUE("lightskyblue"), - LIGHTSLATEGRAY("lightslategray"), - LIGHTSTEELBLUE("lightsteelblue"), - LIGHTYELLOW("lightyellow"), - LIME("lime"), - LIMEGREEN("limegreen"), - LINEN("linen"), - MAGENTA("magenta"), - MAROON("maroon"), - MEDIUMAQUAMARINE("mediumaquamarine"), - MEDIUMBLUE("mediumblue"), - MEDIUMORCHID("mediumorchid"), - MEDIUMPURPLE("mediumpurple"), - MEDIUMSEAGREEN("mediumseagreen"), - MEDIUMSLATEBLUE("mediumslateblue"), - MEDIUMSPRINGGREEN("mediumspringgreen"), - MEDIUMTURQUOISE("mediumturquoise"), - MEDIUMVIOLETRED("mediumvioletred"), - MIDNIGHTBLUE("midnightblue"), - MINTCREAM("mintcream"), - MISTYROSE("mistyrose"), - MOCCASIN("moccasin"), - NAVAJOWHITE("navajowhite"), - NAVY("navy"), - OLDLACE("oldlace"), - OLIVE("olive"), - OLIVEDRAB("olivedrab"), - ORANGE("orange"), - ORANGERED("orangered"), - ORCHID("orchid"), - PALEGOLDENROD("palegoldenrod"), - PALEGREEN("palegreen"), - PALETURQUOISE("paleturquoise"), - PALEVIOLETRED("palevioletred"), - PAPAYAWHIP("papayawhip"), - PEACHPUFF("peachpuff"), - PERU("peru"), - PINK("pink"), - PLUM("plum"), - POWDERBLUE("powderblue"), - PURPLE("purple"), - REBECCAPURPLE("rebeccapurple"), - RED("red"), - ROSYBROWN("rosybrown"), - ROYALBLUE("royalblue"), - SADDLEBROWN("saddlebrown"), - SALMON("salmon"), - SANDYBROWN("sandybrown"), - SEAGREEN("seagreen"), - SEASHELL("seashell"), - SIENNA("sienna"), - SILVER("silver"), - SKYBLUE("skyblue"), - SLATEBLUE("slateblue"), - SLATEGRAY("slategray"), - SNOW("snow"), - SPRINGGREEN("springgreen"), - STEELBLUE("steelblue"), - TAN("tan"), - TEAL("teal"), - THISTLE("thistle"), - TOMATO("tomato"), - TURQUOISE("turquoise"), - VIOLET("violet"), - WHEAT("wheat"), - WHITE("white"), - WHITESMOKE("whitesmoke"), - YELLOW("yellow"), - YELLOWGREEN("yellowgreen") -} - -/** - * Definitions of CSS background size. - */ -enum class BgSize(internal val size: String) { - COVER("cover"), - CONTAIN("contain") -} - -/** - * Definitions of CSS background repeat options. - */ -enum class BgRepeat(internal val repeat: String) { - REPEAT("repeat"), - REPEATX("repeat-x"), - REPEATY("repeat-y"), - NOREPEAT("no-repeat") -} - -/** - * Definitions of CSS background attachment options. - */ -enum class BgAttach(internal val attachment: String) { - SCROLL("scroll"), - FIXED("fixed"), - LOCAL("local") -} - -/** - * Definitions of CSS background origin options. - */ -enum class BgOrigin(internal val origin: String) { - PADDING("padding-box"), - BORDER("border-box"), - CONTENT("content-box") -} - -/** - * Definitions of CSS background clipping options. - */ -enum class BgClip(internal val clip: String) { - PADDING("padding-box"), - BORDER("border-box"), - CONTENT("content-box") -} - -/** - * Definitions of CSS position options. - */ -enum class Position(internal val position: String) { - STATIC("static"), - RELATIVE("relative"), - FIXED("fixed"), - ABSOLUTE("absolute"), - STICKY("sticky") -} - -/** - * Definitions of CSS overflow options. - */ -enum class Overflow(internal val overflow: String) { - VISIBLE("visible"), - HIDDEN("hidden"), - SCROLL("scroll"), - AUTO("auto"), - INITIAL("initial"), - INHERIT("inherit") -} - -/** - * Definitions of CSS resize options. - */ -enum class Resize(internal val resize: String) { - NONE("none"), - BOTH("both"), - HORIZONTAL("horizontal"), - VERTICAL("vertical"), - INITIAL("initial"), - INHERIT("inherit") -} - -/** - * Type-safe definition of CSS border. - */ -class Border private constructor( - private val width: CssSize? = null, private val style: BorderStyle? = null, - private val color: String? = null -) { - /** - * Creates CSS Border with given width and style. - * @param width width of the border - * @param style style of the border - */ - constructor(width: CssSize? = null, style: BorderStyle? = null) : this(width, style, null) - - /** - * Creates CSS Border with given width, style and color given in hex format. - * @param width width of the border - * @param style style of the border - * @param color color in hex format - */ - constructor(width: CssSize? = null, style: BorderStyle? = null, color: Int) : this( - width, style, - "#" + color.toHexString() - ) - - /** - * Creates CSS Border with given width, style and color given with named constant. - * @param width width of the border - * @param style style of the border - * @param color color named constant - */ - constructor(width: CssSize? = null, style: BorderStyle? = null, color: Col) : this(width, style, color.color) - - internal fun asString(): String { - val w = width?.asString() - return w.orEmpty() + " " + (style?.borderStyle).orEmpty() + " " + color.orEmpty() - } -} - -/** - * Type-safe definition of CSS color. - */ -class Color private constructor(private val color: String? = null) { - /** - * Creates CSS Color with color given in hex format. - * @param color color in hex format - */ - constructor(color: Int) : this("#" + color.toHexString()) - - /** - * Creates CSS Color with color given with named constant. - * @param color color named constant - */ - constructor(color: Col) : this(color.color) - - internal fun asString(): String { - return color.orEmpty() - } -} - -/** - * Type-safe definition of CSS background. - */ -class Background private constructor( - private val color: String? = null, private val image: ResString? = null, - private val positionX: CssSize? = null, private val positionY: CssSize? = null, - private val sizeX: CssSize? = null, private val sizeY: CssSize? = null, - private val size: BgSize? = null, private val repeat: BgRepeat? = null, - private val origin: BgOrigin? = null, private val clip: BgClip? = null, - private val attachment: BgAttach? = null -) { - /** - * Creates CSS Background with given parameters. - * @param image background image - * @param positionX horizontal position of the background image - * @param positionY vertical position of the background image - * @param sizeX horizontal size of the background image - * @param sizeY vertical size of the background image - * @param size resize of the background image - * @param repeat repeat option of the background image - * @param origin origin option of the background image - * @param clip clipping option of the background image - * @param attachment attachment option of the background image - */ - constructor( - image: ResString? = null, positionX: CssSize? = null, positionY: CssSize? = null, - sizeX: CssSize? = null, sizeY: CssSize? = null, size: BgSize? = null, - repeat: BgRepeat? = null, origin: BgOrigin? = null, clip: BgClip? = null, - attachment: BgAttach? = null - ) : this( - null, - image, positionX, positionY, sizeX, sizeY, size, repeat, origin, clip, attachment - ) - - /** - * Creates CSS Background with given parameters. - * @param color color of the background in hex format - * @param image background image - * @param positionX horizontal position of the background image - * @param positionY vertical position of the background image - * @param sizeX horizontal size of the background image - * @param sizeY vertical size of the background image - * @param size resize of the background image - * @param repeat repeat option of the background image - * @param origin origin option of the background image - * @param clip clipping option of the background image - * @param attachment attachment option of the background image - */ - constructor( - color: Int, image: ResString? = null, positionX: CssSize? = null, - positionY: CssSize? = null, - sizeX: CssSize? = null, sizeY: CssSize? = null, size: BgSize? = null, - repeat: BgRepeat? = null, origin: BgOrigin? = null, clip: BgClip? = null, - attachment: BgAttach? = null - ) : this( - "#" + - color.toHexString(), image, positionX, positionY, sizeX, sizeY, size, repeat, origin, clip, - attachment - ) - - /** - * Creates CSS Background with given parameters. - * @param color color of the background with named constant - * @param image background image - * @param positionX horizontal position of the background image - * @param positionY vertical position of the background image - * @param sizeX horizontal size of the background image - * @param sizeY vertical size of the background image - * @param size resize of the background image - * @param repeat repeat option of the background image - * @param origin origin option of the background image - * @param clip clipping option of the background image - * @param attachment attachment option of the background image - */ - constructor( - color: Col, image: ResString? = null, positionX: CssSize? = null, - positionY: CssSize? = null, sizeX: CssSize? = null, sizeY: CssSize? = null, - size: BgSize? = null, repeat: BgRepeat? = null, origin: BgOrigin? = null, clip: BgClip? = null, - attachment: BgAttach? = null - ) : this( - color.color, image, - positionX, positionY, sizeX, sizeY, size, repeat, origin, clip, attachment - ) - - internal fun asString(): String { - val img = image?.let { - "url($image)" - } - val posX = positionX?.asString() - val posY = positionY?.asString() - val sX = sizeX?.asString() - val sY = sizeY?.asString() - return color.orEmpty() + " " + img.orEmpty() + " " + posX.orEmpty() + " " + posY.orEmpty() + - if (sX != null || sY != null || size != null) { - (if (posX != null || posY != null) " / " else " 0px 0px / ") + - sX.orEmpty() + " " + sY.orEmpty() + " " + (size?.size).orEmpty() - } else { - "" - } + " " + (repeat?.repeat).orEmpty() + " " + (origin?.origin).orEmpty() + " " + - (clip?.clip).orEmpty() + " " + (attachment?.attachment).orEmpty() - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt b/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt deleted file mode 100644 index d871ff60..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt +++ /dev/null @@ -1,349 +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.core - -import pl.treksoft.kvision.utils.asString -import kotlin.Unit -import kotlin.reflect.KProperty - -/** - * Base class for components supporting CSS styling. - */ -abstract class StyledComponent : Component { - private val propertyValues: MutableMap<String, Any?> = mutableMapOf() - - /** - * Width of the current component. - */ - open var width: CssSize? by refreshOnUpdate() - /** - * Minimal width of the current component. - */ - var minWidth: CssSize? by refreshOnUpdate() - /** - * Maximal width of the current component. - */ - var maxWidth: CssSize? by refreshOnUpdate() - /** - * Height of the current component. - */ - var height: CssSize? by refreshOnUpdate() - /** - * Minimal height of the current component. - */ - var minHeight: CssSize? by refreshOnUpdate() - /** - * Maximal height of the current component. - */ - var maxHeight: CssSize? by refreshOnUpdate() - /** - * CSS position of the current component. - */ - var position: Position? by refreshOnUpdate() - /** - * Top edge of the current component. - */ - var top: CssSize? by refreshOnUpdate() - /** - * Left edge of the current component. - */ - var left: CssSize? by refreshOnUpdate() - /** - * Right edge of the current component. - */ - var right: CssSize? by refreshOnUpdate() - /** - * Bottom edge of the current component. - */ - var bottom: CssSize? by refreshOnUpdate() - /** - * Z-index of the current component. - */ - var zIndex: Int? by refreshOnUpdate() - /** - * CSS overflow of the current component. - */ - var overflow: Overflow? by refreshOnUpdate() - /** - * CSS resize of the current component. - */ - var resize: Resize? by refreshOnUpdate() - /** - * Border of the current component. - */ - var border: Border? by refreshOnUpdate() - /** - * Top border of the current component. - */ - var borderTop: Border? by refreshOnUpdate() - /** - * Right border of the current component. - */ - var borderRight: Border? by refreshOnUpdate() - /** - * Bottom border of the current component. - */ - var borderBottom: Border? by refreshOnUpdate() - /** - * Left border of the current component. - */ - var borderLeft: Border? by refreshOnUpdate() - /** - * Margin of the current component. - */ - var margin: CssSize? by refreshOnUpdate() - /** - * Top margin of the current component. - */ - var marginTop: CssSize? by refreshOnUpdate() - /** - * Right margin of the current component. - */ - var marginRight: CssSize? by refreshOnUpdate() - /** - * Bottom margin of the current component. - */ - var marginBottom: CssSize? by refreshOnUpdate() - /** - * Left margin of the current component. - */ - var marginLeft: CssSize? by refreshOnUpdate() - /** - * Padding of the current component. - */ - var padding: CssSize? by refreshOnUpdate() - /** - * Top padding of the current component. - */ - var paddingTop: CssSize? by refreshOnUpdate() - /** - * Right padding of the current component. - */ - var paddingRight: CssSize? by refreshOnUpdate() - /** - * Bottom padding of the current component. - */ - var paddingBottom: CssSize? by refreshOnUpdate() - /** - * Left padding of the current component. - */ - var paddingLeft: CssSize? by refreshOnUpdate() - /** - * Text color for the current component. - */ - var color: Color? by refreshOnUpdate() - /** - * Text color for the current component given in hex format (write only). - * - * This property gives a convenient way to set the value of [color] property e.g.: - * - * c.colorHex = 0x00ff00 - * - * The value read from this property is always null. - */ - var colorHex: Int? - get() = null - set(value) { - color = if (value != null) Color(value) else null - } - /** - * Text color for the current component given with named constant (write only). - * - * This property gives a convenient way to set the value of [color] property e.g.: - * - * c.colorName = Col.GREEN - * - * The value read from this property is always null. - */ - var colorName: Col? - get() = null - set(value) { - color = if (value != null) Color(value) else null - } - /** - * Opacity of the current component. - */ - var opacity: Double? by refreshOnUpdate() - /** - * Background of the current component. - */ - var background: Background? by refreshOnUpdate() - - private var snStyleCache: List<StringPair>? = null - - /** - * @suppress - * Internal function - * Re-renders the current component. - * @return current component - */ - open fun refresh(): StyledComponent { - snStyleCache = null - return this - } - - internal fun getSnStyleInternal(): List<StringPair> { - return snStyleCache ?: { - val s = getSnStyle() - snStyleCache = s - s - }() - } - - /** - * Returns the list of String pairs defining CSS style attributes and their values. - * @return the list of attributes and their values - */ - @Suppress("ComplexMethod", "LongMethod") - protected open fun getSnStyle(): List<StringPair> { - val snstyle = mutableListOf<StringPair>() - width?.let { - snstyle.add("width" to it.asString()) - } - minWidth?.let { - snstyle.add("min-width" to it.asString()) - } - maxWidth?.let { - snstyle.add("max-width" to it.asString()) - } - height?.let { - snstyle.add("height" to it.asString()) - } - minHeight?.let { - snstyle.add("min-height" to it.asString()) - } - maxHeight?.let { - snstyle.add("max-height" to it.asString()) - } - position?.let { - snstyle.add("position" to it.position) - } - top?.let { - snstyle.add("top" to it.asString()) - } - left?.let { - snstyle.add("left" to it.asString()) - } - right?.let { - snstyle.add("right" to it.asString()) - } - bottom?.let { - snstyle.add("bottom" to it.asString()) - } - zIndex?.let { - snstyle.add("z-index" to it.toString()) - } - overflow?.let { - snstyle.add("overflow" to it.toString()) - } - resize?.let { - snstyle.add("resize" to it.toString()) - } - border?.let { - snstyle.add("border" to it.asString()) - } - borderTop?.let { - snstyle.add("border-top" to it.asString()) - } - borderRight?.let { - snstyle.add("border-right" to it.asString()) - } - borderBottom?.let { - snstyle.add("border-bottom" to it.asString()) - } - borderLeft?.let { - snstyle.add("border-left" to it.asString()) - } - margin?.let { - snstyle.add("margin" to it.asString()) - } - marginTop?.let { - snstyle.add("margin-top" to it.asString()) - } - marginRight?.let { - snstyle.add("margin-right" to it.asString()) - } - marginBottom?.let { - snstyle.add("margin-bottom" to it.asString()) - } - marginLeft?.let { - snstyle.add("margin-left" to it.asString()) - } - padding?.let { - snstyle.add("padding" to it.asString()) - } - paddingTop?.let { - snstyle.add("padding-top" to it.asString()) - } - paddingRight?.let { - snstyle.add("padding-right" to it.asString()) - } - paddingBottom?.let { - snstyle.add("padding-bottom" to it.asString()) - } - paddingLeft?.let { - snstyle.add("padding-left" to it.asString()) - } - color?.let { - snstyle.add("color" to it.asString()) - } - opacity?.let { - snstyle.add("opacity" to it.toString()) - } - background?.let { - snstyle.add("background" to it.asString()) - } - return snstyle - } - - internal fun <T> refreshOnUpdate(refreshFunction: ((T) -> Unit) = { this.refresh() }) = - RefreshDelegateProvider<T>(null, refreshFunction) - - internal fun <T> refreshOnUpdate(initialValue: T, refreshFunction: ((T) -> Unit) = { this.refresh() }) = - RefreshDelegateProvider(initialValue, refreshFunction) - - internal inner class RefreshDelegateProvider<T>( - private val initialValue: T?, private val refreshFunction: (T) -> Unit - ) { - operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): RefreshDelegate<T> { - if (initialValue != null) propertyValues[prop.name] = initialValue - return RefreshDelegate(refreshFunction) - } - } - - internal inner class RefreshDelegate<T>(private val refreshFunction: ((T) -> Unit)) { - @Suppress("UNCHECKED_CAST") - operator fun getValue(thisRef: StyledComponent, property: KProperty<*>): T { - val value = propertyValues[property.name] - return if (value != null) { - value as T - } else { - null as T - } - } - - operator fun setValue(thisRef: StyledComponent, property: KProperty<*>, value: T) { - propertyValues[property.name] = value - refreshFunction(value) - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Types.kt b/src/main/kotlin/pl/treksoft/kvision/core/Types.kt deleted file mode 100644 index 0817b3ae..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/core/Types.kt +++ /dev/null @@ -1,44 +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.core - - /** - * This type is used for accessing resources with CommonJS **require** function. - * - * e.g. require("./img/picture.png") - */ -typealias ResString = String - - /** - * Helper type used to define CSS style attributes. - */ -typealias StringPair = Pair<String, String> - - /** - * Helper type used to define CSS classes. - */ -typealias StringBoolPair = Pair<String, Boolean> - - /** - * This type is used for defining CSS dimensions (width, heights, margins, paddings, etc.). - */ -typealias CssSize = Pair<Int, UNIT> diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt deleted file mode 100644 index ac3ba143..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ /dev/null @@ -1,585 +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.core - -import com.github.snabbdom.VNode -import com.github.snabbdom.VNodeData -import com.github.snabbdom.h -import org.w3c.dom.CustomEventInit -import org.w3c.dom.DragEvent -import org.w3c.dom.Node -import pl.treksoft.jquery.JQuery -import pl.treksoft.jquery.jQuery -import pl.treksoft.kvision.KVManager -import pl.treksoft.kvision.panel.Root -import pl.treksoft.kvision.utils.SnOn -import pl.treksoft.kvision.utils.hooks -import pl.treksoft.kvision.utils.on -import pl.treksoft.kvision.utils.snAttrs -import pl.treksoft.kvision.utils.snClasses -import pl.treksoft.kvision.utils.snOpt -import pl.treksoft.kvision.utils.snStyle - -/** - * Base widget class. The parent of all component classes. - * - * A simple widget is rendered as HTML DIV element. - * - * @constructor Creates basic Widget with given CSS class names. - * @param classes Set of CSS class names - */ -@Suppress("TooManyFunctions", "LargeClass") -open class Widget(classes: Set<String> = setOf()) : StyledComponent() { - - internal val classes = classes.toMutableSet() - internal val surroundingClasses: MutableSet<String> = mutableSetOf() - internal val internalListeners = mutableListOf<SnOn<Widget>.() -> Unit>() - internal val listeners = mutableListOf<SnOn<Widget>.() -> Unit>() - - override var parent: Component? = null - - override var visible: Boolean = true - set(value) { - val oldField = field - field = value - if (oldField != field) refresh() - } - /** - * A title attribute of generated HTML element. - */ - var title: String? by refreshOnUpdate() - /** - * An ID attribute of generated HTML element. - */ - var id: String? by refreshOnUpdate() - /** - * A role attribute of generated HTML element. - */ - var role: String? by refreshOnUpdate() - /** - * Determines if the current widget is draggable. - */ - var draggable: Boolean? by refreshOnUpdate() - - internal var surroundingSpan by refreshOnUpdate(false) - - internal var eventTarget: Widget? = null - - private var vnode: VNode? = null - - private var snAttrsCache: List<StringPair>? = null - private var snClassCache: List<StringBoolPair>? = null - private var snOnCache: com.github.snabbdom.On? = null - private var snHooksCache: com.github.snabbdom.Hooks? = null - - internal fun <T> singleRender(block: () -> T): T { - getRoot()?.renderDisabled = true - val t = block() - getRoot()?.renderDisabled = false - getRoot()?.reRender() - return t - } - - override fun renderVNode(): VNode { - return if (surroundingClasses.isEmpty()) { - if (surroundingSpan) { - h("span", arrayOf(render())) - } else { - render() - } - } else { - val opt = snOpt { - `class` = snClasses(surroundingClasses.map { c -> c to true }) - } - if (surroundingSpan) { - h("div", opt, arrayOf(h("span", arrayOf(render())))) - } else { - h("div", opt, arrayOf(render())) - } - } - } - - /** - * Renders current component as a Snabbdom vnode. - * @return Snabbdom vnode - */ - protected open fun render(): VNode { - return render("div") - } - - /** - * Renders current component as a Snabbdom vnode. - * @param elementName HTML element name - * @return Snabbdom vnode - */ - protected open fun render(elementName: String): VNode { - return h(elementName, getSnOpt()) - } - - /** - * Renders current component as a Snabbdom vnode. - * @param elementName HTML element name - * @param children array of children nodes - * @return Snabbdom vnode - */ - protected open fun render(elementName: String, children: Array<dynamic>): VNode { - return h(elementName, getSnOpt(), children) - } - - /** - * Generates VNodeData to creating Snabbdom VNode. - * - * Optimizes creating process by keeping configuration attributes in a cache. - */ - private fun getSnOpt(): VNodeData { - return snOpt { - attrs = snAttrs(getSnAttrsInternal()) - style = snStyle(getSnStyleInternal()) - `class` = snClasses(getSnClassInternal()) - on = getSnOn() - hook = getSnHooksInternal() - } - } - - private fun getSnAttrsInternal(): List<StringPair> { - return snAttrsCache ?: { - val s = getSnAttrs() - snAttrsCache = s - s - }() - } - - private fun getSnClassInternal(): List<StringBoolPair> { - return snClassCache ?: { - val s = getSnClass() - snClassCache = s - s - }() - } - - private fun getSnHooksInternal(): com.github.snabbdom.Hooks? { - return snHooksCache ?: { - val s = getSnHooks() - snHooksCache = s - s - }() - } - - /** - * Returns list of CSS class names for current widget in the form of a List<StringBoolPair>. - * @return list of CSS class names - */ - protected open fun getSnClass(): List<StringBoolPair> { - return classes.map { c -> c to true } + if (visible) listOf() else listOf("hidden" to true) - } - - /** - * Returns list of element attributes in the form of a List<StringPair>. - * @return list of element attributes - */ - protected open fun getSnAttrs(): List<StringPair> { - val snattrs = mutableListOf<StringPair>() - id?.let { - snattrs.add("id" to it) - } - title?.let { - snattrs.add("title" to it) - } - role?.let { - snattrs.add("role" to it) - } - if (draggable == true) { - snattrs.add("draggable" to "true") - } - return snattrs - } - - /** - * Returns list of event handlers in the form of a Snabbdom *On* object. - * @return list of event handlers - */ - protected open fun getSnOn(): com.github.snabbdom.On? { - return if (internalListeners.size > 0 || listeners.size > 0) { - val internalHandlers = on(this) - internalListeners.forEach { l -> (internalHandlers::apply)(l) } - val handlers = on(eventTarget ?: this) - listeners.forEach { l -> (handlers::apply)(l) } - if (internalHandlers.click != null) { - if (handlers.click == null) { - handlers.click = internalHandlers.click - } else { - val intc = internalHandlers.click - val c = handlers.click - handlers.click = { e -> - intc?.invoke(e) - c?.invoke(e) - } - } - } - if (internalHandlers.change != null) { - if (handlers.change == null) { - handlers.change = internalHandlers.change - } else { - val intc = internalHandlers.change - val c = handlers.change - handlers.change = { e -> - intc?.invoke(e) - c?.invoke(e) - } - } - } - if (internalHandlers.input != null) { - if (handlers.input == null) { - handlers.input = internalHandlers.input - } else { - val intc = internalHandlers.input - val c = handlers.input - handlers.input = { e -> - intc?.invoke(e) - c?.invoke(e) - } - } - } - handlers - } else { - null - } - } - - /** - * Returns list of hooks in the form of a Snabbdom *Hooks* object. - * @return list of hooks - */ - protected open fun getSnHooks(): com.github.snabbdom.Hooks? { - val hooks = hooks() - hooks.apply { - create = { _, v -> - vnode = v - afterCreate(v) - } - insert = { v -> - vnode = v - afterInsert(v) - } - postpatch = { ov, v -> - vnode = v - if (ov.elm !== v.elm) { - afterInsert(v) - } else { - afterPostpatch(v) - } - } - destroy = { _ -> - afterDestroy() - vnode = null - vnode - } - } - return hooks - } - - /** - * @suppress - * Internal function - */ - @Suppress("UNCHECKED_CAST") - protected fun <T : Widget> setInternalEventListener(block: SnOn<T>.() -> Unit): Widget { - internalListeners.add(block as SnOn<Widget>.() -> Unit) - refresh() - return this - } - - /** - * @suppress - * Internal function - */ - protected fun setInternalEventListener(block: SnOn<Widget>.() -> Unit): Widget { - internalListeners.add(block) - refresh() - return this - } - - /** - * Sets an event listener for current widget, keeping the actual type of component. - * @param T widget type - * @param block event handler - * @return current widget - * - * Example: - * - * button.setEventListener<Button> { - * dblclick = { - * Alert.show("Button double clicked!") - * // self is of type Button here - * } - * } - */ - @Suppress("UNCHECKED_CAST") - open fun <T : Widget> setEventListener(block: SnOn<T>.() -> Unit): Widget { - listeners.add(block as SnOn<Widget>.() -> Unit) - refresh() - return this - } - - /** - * Sets an event listener for current widget. - * @param block event handler - * @return current widget - * - * Example: - * - * button.setEventListener { - * dblclick = { - * Alert.show("Button double clicked!") - * // self is of type Widget here - * } - * } - */ - open fun setEventListener(block: SnOn<Widget>.() -> Unit): Widget { - listeners.add(block) - refresh() - return this - } - - /** - * Removes all event listeners from current widget. - * @return current widget - */ - open fun removeEventListeners(): Widget { - listeners.clear() - refresh() - return this - } - - /** - * Makes current widget visible. - * @return current widget - */ - open fun show(): Widget { - visible = true - return this - } - - /** - * Makes current widget invisible. - * @return current widget - */ - open fun hide(): Widget { - visible = false - return this - } - - /** - * Toggles visibility of current widget. - * @return current widget - */ - open fun toggleVisible(): Widget { - return if (visible) hide() else show() - } - - override fun addCssClass(css: String): Widget { - this.classes.add(css) - refresh() - return this - } - - override fun removeCssClass(css: String): Widget { - this.classes.remove(css) - refresh() - return this - } - - override fun addSurroundingCssClass(css: String): Widget { - this.surroundingClasses.add(css) - refresh() - return this - } - - override fun removeSurroundingCssClass(css: String): Widget { - this.surroundingClasses.remove(css) - refresh() - return this - } - - override fun getElement(): Node? { - return this.vnode?.elm - } - - override fun getElementJQuery(): JQuery? { - return getElement()?.let { jQuery(it) } - } - - override fun getElementJQueryD(): dynamic { - return getElement()?.let { jQuery(it).asDynamic() } - } - - override fun clearParent(): Widget { - this.parent = null - return this - } - - override fun refresh(): Widget { - super.refresh() - snAttrsCache = null - snClassCache = null - snOnCache = null - snHooksCache = null - getRoot()?.reRender() - return this - } - - /** - * Method called after creating Snabbdom vnode. - */ - protected open fun afterCreate(node: VNode) { - } - - /** - * Method called after inserting Snabbdom vnode into the DOM. - */ - protected open fun afterInsert(node: VNode) { - } - - /** - * Method called after updating Snabbdom vnode. - */ - protected open fun afterPostpatch(node: VNode) { - } - - /** - * Method called after destroying Snabbdom vnode. - */ - protected open fun afterDestroy() { - } - - override fun getRoot(): Root? { - return this.parent?.getRoot() - } - - /** - * Sets D&D data for the current widget. It also makes it draggable. - * @param format D&D data format - * @param data D&D data transferred to a drop target - */ - open fun setDragDropData(format: String, data: String) { - draggable = true - setEventListener<Widget> { - dragstart = { e -> - e.dataTransfer?.setData(format, data) - } - } - } - - /** - * Clears D&D data for the current widget. It also makes it not draggable. - */ - open fun clearDragDropData() { - draggable = false - setEventListener<Widget> { - dragstart = { - } - } - } - - /** - * Sets the current widget as a D&D drop target with helper callback accepting String data. - * @param format accepted D&D data format - * @param callback a callback function accepting String data called after any drop event - */ - open fun setDropTargetData(format: String, callback: (String?) -> Unit) { - setDropTarget(format) { e -> - callback(e.dataTransfer?.getData(format)) - } - } - - /** - * Sets the current widget as a D&D drop target. - * @param format accepted D&D data format - * @param callback a callback function accepting event object called after any drop event - */ - open fun setDropTarget(format: String, callback: (DragEvent) -> Unit) { - setDropTarget(setOf(format), callback) - } - - /** - * Sets the current widget as a D&D drop target. - * @param formats a set of accepted D&D data formats - * @param callback a callback function accepting event object called after any drop event - */ - open fun setDropTarget(formats: Set<String>? = null, callback: (DragEvent) -> Unit) { - setEventListener<Widget> { - dragover = { e -> - val types = e.dataTransfer?.types?.toSet() ?: setOf() - if (formats == null || formats.intersect(types).isNotEmpty()) { - e.preventDefault() - } - } - drop = { e -> - e.preventDefault() - e.stopPropagation() - callback(e) - } - } - } - - /** - * @suppress - * Internal function - */ - protected open fun createLabelWithIcon( - label: String, icon: String? = null, - image: ResString? = null - ): Array<out Any> { - return if (icon != null) { - if (icon.startsWith("fa-")) { - arrayOf(KVManager.virtualize("<i class='fa $icon'></i>"), " " + label) - } else { - arrayOf(KVManager.virtualize("<span class='glyphicon glyphicon-$icon'></span>"), " " + label) - } - } else if (image != null) { - arrayOf(KVManager.virtualize("<img src='$image' alt='' />"), " " + label) - } else { - arrayOf(label) - } - } - - internal open fun dispatchEvent(type: String, eventInitDict: CustomEventInit): Boolean? { - val event = org.w3c.dom.CustomEvent(type, eventInitDict) - return this.getElement()?.dispatchEvent(event) - } - - override fun dispose() { - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.widget(classes: Set<String> = setOf(), init: (Widget.() -> Unit)? = null): Widget { - val widget = Widget(classes).apply { init?.invoke(this) } - this.add(widget) - return widget - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/core/WidgetWrapper.kt b/src/main/kotlin/pl/treksoft/kvision/core/WidgetWrapper.kt deleted file mode 100644 index e5d9ebbd..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/core/WidgetWrapper.kt +++ /dev/null @@ -1,74 +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.core - -import com.github.snabbdom.VNode -import kotlin.Unit - -/** - * This class allows to wrap a component into separately styled DIV element. - * - * @constructor - * @param wrapped wrapped component - * @param classes Set of CSS class names - */ -open class WidgetWrapper(internal var wrapped: Component?, classes: Set<String> = setOf()) : Widget(classes) { - - override var visible - get() = wrapped?.visible == true - set(value) { - wrapped?.visible = value - } - - init { - @Suppress("LeakingThis") - wrapped?.parent = this - } - - override fun render(): VNode { - return wrapped?.let { - render("div", arrayOf(it.renderVNode())) - } ?: render("div") - } - - override fun dispose() { - wrapped?.clearParent() - wrapped = null - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.widgetWrapper( - wrapped: Component?, - classes: Set<String> = setOf(), - init: (WidgetWrapper.() -> Unit)? = null - ): WidgetWrapper { - val widgetWrapper = WidgetWrapper(wrapped, classes).apply { init?.invoke(this) } - this.add(widgetWrapper) - return widgetWrapper - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/data/DataComponent.kt b/src/main/kotlin/pl/treksoft/kvision/data/DataComponent.kt deleted file mode 100644 index 4e5b92d5..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/data/DataComponent.kt +++ /dev/null @@ -1,54 +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.data - -import kotlin.properties.ObservableProperty -import kotlin.properties.ReadWriteProperty -import kotlin.reflect.KProperty - -/** - * Base interface for observable data model. - */ -interface DataComponent { - /** - * @suppress - * Internal property - */ - var container: DataUpdatable? - - /** - * @suppress - * Internal function for observable properties - */ - fun <T> obs(initialValue: T): ReadWriteProperty<Any?, T> = object : ObservableProperty<T>(initialValue) { - override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) { - container?.update() - } - } -} - -/** - * Base abstract class for creating observable data model. - */ -abstract class BaseDataComponent : DataComponent { - override var container: DataUpdatable? = null -} diff --git a/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt b/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt deleted file mode 100644 index c008c47b..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt +++ /dev/null @@ -1,144 +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.data - -import com.github.snabbdom.VNode -import com.lightningkite.kotlin.observable.list.ObservableList -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.panel.VPanel - -/** - * A container class with support for observable data model. - * - * @constructor Creates DataContainer bound to given data model. - * @param M base data model type - * @param C base component type - * @param model data model of type *ObservableList<M>* - * @param binding a function which creates component C from data model at given index - * @param child internal container (defaults to [VPanel]) - * @param init an initializer extension function - */ -class DataContainer<M : DataComponent, C : Component>( - private val model: ObservableList<M>, - private val binding: (Int) -> C, - private val child: Container = VPanel(), - init: (DataContainer<M, C>.() -> Unit)? = null -) : - Widget(setOf()), Container, DataUpdatable { - - override var visible - get() = child.visible - set(value) { - child.visible = value - } - - internal var onUpdateHandler: (() -> Unit)? = null - - init { - child.parent = this - model.onUpdate += { _ -> - update() - } - update() - @Suppress("LeakingThis") - init?.invoke(this) - } - - override fun add(child: Component): Container { - this.child.add(child) - return this - } - - override fun addAll(children: List<Component>): Container { - this.child.addAll(children) - return this - } - - override fun remove(child: Component): Container { - this.child.remove(child) - return this - } - - override fun removeAll(): Container { - this.child.removeAll() - return this - } - - override fun getChildren(): List<Component> { - return this.child.getChildren() - } - - override fun renderVNode(): VNode { - return this.child.renderVNode() - } - - /** - * Updates view from the current data model state. - */ - override fun update() { - model.forEach { it.container = this } - singleRender { - child.removeAll() - child.addAll(model.mapIndexed { index, _ -> binding(index) }) - } - onUpdateHandler?.invoke() - } - - /** - * Sets a notification handler called after every update. - * @param handler notification handler - * @return current container - */ - fun onUpdate(handler: () -> Unit): DataContainer<M, C> { - onUpdateHandler = handler - return this - } - - /** - * Clears notification handler. - * @return current container - */ - fun clearOnUpdate(): DataContainer<M, C> { - onUpdateHandler = null - return this - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun <M : DataComponent, C : Component> Container.dataContainer( - model: ObservableList<M>, - binding: (Int) -> C, - child: Container = VPanel(), - init: (DataContainer<M, C>.() -> Unit)? = null - ): DataContainer<M, C> { - val dataContainer = DataContainer(model, binding, child, init) - this.add(dataContainer) - return dataContainer - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/data/DataUpdatable.kt b/src/main/kotlin/pl/treksoft/kvision/data/DataUpdatable.kt deleted file mode 100644 index 7c54e864..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/data/DataUpdatable.kt +++ /dev/null @@ -1,29 +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.data - -/** - * Interface for updatable container. - */ -interface DataUpdatable { - fun update() -} diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt deleted file mode 100644 index 3ea85d4a..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt +++ /dev/null @@ -1,276 +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.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.StringBoolPair -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.html.ButtonStyle -import pl.treksoft.kvision.html.Button -import pl.treksoft.kvision.html.ListType -import pl.treksoft.kvision.html.Link -import pl.treksoft.kvision.html.ListTag -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag -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") -} - -/** - * 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 disabled determines if the component is disabled on start - * @param classes a set of CSS class names - */ -open class DropDown( - text: String, elements: List<StringPair>? = null, icon: String? = null, - style: ButtonStyle = ButtonStyle.DEFAULT, disabled: 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 - } - /** - * Determines if the dropdown is showing upwards. - */ - var dropup by refreshOnUpdate(false) - /** - * 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, setOf("dropdown") - ) - internal val list: DropDownListTag = DropDownListTag(idc, setOf("dropdown-menu")) - - init { - setChildrenFromElements() - this.addInternal(button) - this.addInternal(list) - counter++ - } - - 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 -> Tag(TAG.LI, it.first, classes = setOf("dropdown-header")) - DD.SEPARATOR.option -> { - val tag = Tag(TAG.LI, it.first, classes = setOf("divider")) - tag.role = "separator" - tag - } - DD.DISABLED.option -> { - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(Link(it.first, "#")) - tag - } - else -> Link(it.first, it.second) - } - } - 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 (dropup) - cl.add("dropup" to true) - else - cl.add("dropdown" to true) - return cl - } - - /** - * Toggles dropdown visibility. - */ - open fun toggle() { - this.list.getElementJQueryD()?.dropdown("toggle") - } - - 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.DEFAULT, disabled: Boolean = false, - classes: Set<String> = setOf(), init: (DropDown.() -> Unit)? = null - ): DropDown { - val dropDown = DropDown(text, elements, icon, style, disabled, classes).apply { init?.invoke(this) } - this.add(dropDown) - return dropDown - } - } -} - -internal class DropDownButton( - id: String, text: String, icon: String? = null, style: ButtonStyle = ButtonStyle.DEFAULT, - disabled: Boolean = false, classes: Set<String> = setOf() -) : - Button(text, icon, style, disabled, classes) { - - init { - this.id = id - } - - override fun getSnAttrs(): List<StringPair> { - return super.getSnAttrs() + listOf( - "data-toggle" to "dropdown", "aria-haspopup" to "true", - "aria-expanded" to "false" - ) - } -} - -internal class DropDownListTag(private val ariaId: String, classes: Set<String> = setOf()) : ListTag( - ListType.UL, null, - false, classes -) { - - override fun getSnAttrs(): List<StringPair> { - return super.getSnAttrs() + listOf("aria-labelledby" to ariaId) - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FieldLabel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FieldLabel.kt deleted file mode 100644 index b4be8f8e..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/FieldLabel.kt +++ /dev/null @@ -1,49 +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.form - -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag - -/** - * Helper class for HTML label element. - * - * @constructor - * @param forId the value of *for* attribute - * @param text the text of the label - * @param rich determines if [text] can contain HTML code - * @param classes a set of CSS class names - */ -open class FieldLabel( - internal val forId: String, text: String? = null, rich: Boolean = false, - classes: Set<String> = setOf("control-label") -) : Tag( - TAG.LABEL, - text, rich, classes = classes -) { - - override fun getSnAttrs(): List<StringPair> { - return super.getSnAttrs() + ("for" to forId) - } - -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/Form.kt b/src/main/kotlin/pl/treksoft/kvision/form/Form.kt deleted file mode 100644 index e91002e9..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/Form.kt +++ /dev/null @@ -1,212 +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.form - -import kotlin.js.Date -import kotlin.js.Json - -/** - * Internal data class containing form field parameters. - */ -internal data class FieldParams<in F : FormControl>( - val required: Boolean = false, - val validatorMessage: ((F) -> String?)? = null, - val validator: ((F) -> Boolean?)? = null -) - -/** - * The form definition class. Can be used directly or indirectly inside a [FormPanel]. - * - * @constructor Creates a form with a given modelFactory function - * @param K model class type - * @param panel optional instance of [FormPanel] - * @param modelFactory function transforming a Map<String, Any?> to a data model of class K - */ -class Form<K>(private val panel: FormPanel<K>? = null, private val modelFactory: (Map<String, Any?>) -> K) { - - internal val fields: MutableMap<String, FormControl> = mutableMapOf() - internal val fieldsParams: MutableMap<String, Any> = mutableMapOf() - internal var validatorMessage: ((Form<K>) -> String?)? = null - internal var validator: ((Form<K>) -> Boolean?)? = null - - /** - * Adds a control to the form. - * @param key key identifier of the control - * @param control the form control - * @param required determines if the control is required - * @param validatorMessage optional function returning validation message - * @param validator optional validation function - * @return current form - */ - fun <C : FormControl> add( - key: String, control: C, required: Boolean = false, - validatorMessage: ((C) -> String?)? = null, - validator: ((C) -> Boolean?)? = null - ): Form<K> { - this.fields[key] = control - this.fieldsParams[key] = FieldParams(required, validatorMessage, validator) - return this - } - - /** - * Removes a control from the form. - * @param key key identifier of the control - * @return current form - */ - fun remove(key: String): Form<K> { - this.fields.remove(key) - return this - } - - /** - * Removes all controls from the form. - * @return current form - */ - fun removeAll(): Form<K> { - this.fields.clear() - return this - } - - /** - * Returns a control of given key. - * @param key key identifier of the control - * @return selected control - */ - fun getControl(key: String): FormControl? { - return this.fields[key] - } - - /** - * Returns a value of the control of given key. - * @param key key identifier of the control - * @return value of the control - */ - operator fun get(key: String): Any? { - return getControl(key)?.getValue() - } - - /** - * Sets the values of all the controls from the model. - * @param model data model - */ - fun setData(model: K) { - fields.forEach { it.value.setValue(null) } - val map = model.asDynamic().map as? Map<String, Any?> - if (map != null) { - map.forEach { - fields[it.key]?.setValue(it.value) - } - } else { - for (key in js("Object").keys(model)) { - @Suppress("UnsafeCastFromDynamic") - fields[key]?.setValue(model.asDynamic()[key]) - } - } - } - - /** - * Sets the values of all controls to null. - */ - fun clearData() { - fields.forEach { it.value.setValue(null) } - } - - /** - * Returns current data model. - * @return data model - */ - fun getData(): K { - val map = fields.entries.associateBy({ it.key }, { it.value.getValue() }) - return modelFactory(map.withDefault { null }) - } - - /** - * Returns current data model as JSON. - * @return data model as JSON - */ - fun getDataJson(): Json { - return fields.entries.associateBy({ it.key }, { it.value.getValue() }).asJson() - } - - /** - * Invokes validator function and validates the form. - * @return validation result - */ - fun validate(): Boolean { - val fieldWithError = fieldsParams.mapNotNull { entry -> - fields[entry.key]?.let { control -> - @Suppress("UNCHECKED_CAST") - val fieldsParams = (entry.value as? FieldParams<FormControl>) - val required = fieldsParams?.required ?: false - val requiredError = control.getValue() == null && required - if (requiredError) { - control.validatorError = "Value is required" - true - } else { - val validatorPassed = fieldsParams?.validator?.invoke(control) ?: true - control.validatorError = if (!validatorPassed) { - fieldsParams?.validatorMessage?.invoke(control) ?: "Invalid value" - } else { - null - } - !validatorPassed - } - } - }.find { it } - val validatorPassed = validator?.invoke(this) ?: true - panel?.validatorError = if (!validatorPassed) { - validatorMessage?.invoke(this) ?: "Invalid form data" - } else { - null - } - return fieldWithError == null && validatorPassed - } -} - -/** - * Returns given value from the map as a String. - */ -fun Map<String, Any?>.string(key: String): String? = this[key] as? String - -/** - * Returns given value from the map as a Number. - */ -fun Map<String, Any?>.number(key: String): Number? = this[key] as? Number - -/** - * Returns given value from the map as a Boolean. - */ -fun Map<String, Any?>.bool(key: String): Boolean? = this[key] as? Boolean - -/** - * Returns given value from the map as a Date. - */ -fun Map<String, Any?>.date(key: String): Date? = this[key] as? Date - -/** - * Returns map values in JSON format. - */ -fun Map<String, Any?>.asJson(): Json { - val array = this.entries.map { it.component1() to it.component2() }.toTypedArray() - @Suppress("SpreadOperator") - return kotlin.js.json(*array) -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt deleted file mode 100644 index 2b974379..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormControl.kt +++ /dev/null @@ -1,163 +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.form - -import pl.treksoft.kvision.core.Component -import kotlin.js.Date - -/** - * Input controls sizes. - */ -enum class InputSize(val className: String) { - LARGE("input-lg"), - SMALL("input-sm") -} - -/** - * Base interface of a form control. - */ -interface FormControl : Component { - /** - * Determines if the field is disabled. - */ - var disabled: Boolean - /** - * Input control size. - */ - var size: InputSize? - /** - * The actual input component. - */ - val input: Component - /** - * Form field label. - */ - val flabel: FieldLabel - /** - * Validation info component. - */ - val validationInfo: HelpBlock - - /** - * Returns the value of the control. - * @return the value - */ - fun getValue(): Any? - - /** - * Sets the value of the control. - * @param v the value - */ - fun setValue(v: Any?) - - /** - * Returns the value of the control as a String. - */ - fun getValueAsString(): String? - - /** - * @suppress - * Internal function - * Re-renders the current component. - * @return current component - */ - fun refresh(): Component - - /** - * Validator error message. - */ - var validatorError: String? - get() = validationInfo.text - set(value) { - validationInfo.text = value - validationInfo.visible = value != null - refresh() - } -} - -/** - * Base interface of a form control with a text value. - */ -interface StringFormControl : FormControl { - /** - * Text value. - */ - var value: String? - - override fun getValue(): String? = value - override fun setValue(v: Any?) { - value = v as? String - } - - override fun getValueAsString(): String? = value -} - -/** - * Base interface of a form control with a numeric value. - */ -interface NumberFormControl : FormControl { - /** - * Numeric value. - */ - var value: Number? - - override fun getValue(): Number? = value - override fun setValue(v: Any?) { - value = v as? Number - } - - override fun getValueAsString(): String? = value?.toString() -} - -/** - * Base interface of a form control with a boolean value. - */ -interface BoolFormControl : FormControl { - /** - * Boolean value. - */ - var value: Boolean - - override fun getValue(): Boolean = value - override fun setValue(v: Any?) { - value = v as? Boolean ?: false - } - - override fun getValueAsString(): String? = value.toString() -} - -/** - * Base interface of a form control with a date value. - */ -interface DateFormControl : FormControl { - /** - * Date value. - */ - var value: Date? - - override fun getValue(): Date? = value - override fun setValue(v: Any?) { - value = v as? Date - } - - override fun getValueAsString(): String? = value?.toString() -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt deleted file mode 100644 index c13fe9f1..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt +++ /dev/null @@ -1,234 +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.form - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.form.check.CheckBox -import pl.treksoft.kvision.form.check.Radio -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag -import pl.treksoft.kvision.panel.SimplePanel -import kotlin.js.Json - -/** - * Bootstrap form layout options. - */ -enum class FormType(internal val formType: String) { - INLINE("form-inline"), - HORIZONTAL("form-horizontal") -} - -/** - * Bootstrap form component. - * - * @constructor - * @param K model class type - * @param type form layout - * @param classes set of CSS class names - * @param modelFactory function transforming a Map<String, Any?> to a data model of class K - */ -open class FormPanel<K>( - private val type: FormType? = null, classes: Set<String> = setOf(), - modelFactory: (Map<String, Any?>) -> K -) : SimplePanel(classes) { - - /** - * Function returning validation message. - */ - var validatorMessage - get() = form.validatorMessage - set(value) { - form.validatorMessage = value - } - /** - * Validation function. - */ - var validator - get() = form.validator - set(value) { - form.validator = value - } - - internal var validatorError: String? - get() = validationAlert.text - set(value) { - validationAlert.text = value - validationAlert.visible = value != null - refresh() - } - - /** - * @suppress - * Internal property. - */ - @Suppress("LeakingThis") - protected val form = Form(this, modelFactory) - /** - * @suppress - * Internal property. - */ - protected val validationAlert = Tag(TAG.H5, classes = setOf("alert", "alert-danger")).apply { - role = "alert" - visible = false - } - - init { - this.addInternal(validationAlert) - } - - override fun render(): VNode { - return render("form", childrenVNodes()) - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - if (type != null) { - cl.add(type.formType to true) - } - return cl - } - - /** - * Adds a control to the form panel. - * @param key key identifier of the control - * @param control the form control - * @param required determines if the control is required - * @param validatorMessage optional function returning validation message - * @param validator optional validation function - * @return current form panel - */ - open fun <C : FormControl> add( - key: String, control: C, required: Boolean = false, - validatorMessage: ((C) -> String?)? = null, - validator: ((C) -> Boolean?)? = null - ): FormPanel<K> { - if (type == FormType.HORIZONTAL) { - if (control is CheckBox || control is Radio) { - control.addCssClass("col-sm-offset-2") - control.addCssClass("col-sm-10") - } else { - control.flabel.addCssClass("col-sm-2") - control.input.addSurroundingCssClass("col-sm-10") - control.validationInfo.addCssClass("col-sm-offset-2") - control.validationInfo.addCssClass("col-sm-10") - } - } - super.add(control) - form.add(key, control, required, validatorMessage, validator) - return this - } - - /** - * Removes a control from the form panel. - * @param key key identifier of the control - * @return current form panel - */ - open fun remove(key: String): FormPanel<K> { - form.getControl(key)?.let { - super.remove(it) - } - form.remove(key) - return this - } - - override fun removeAll(): FormPanel<K> { - super.removeAll() - this.addInternal(validationAlert) - form.removeAll() - return this - } - - /** - * Returns a control of given key. - * @param key key identifier of the control - * @return selected control - */ - open fun getControl(key: String): FormControl? { - return form.getControl(key) - } - - /** - * Returns a value of the control of given key. - * @param key key identifier of the control - * @return value of the control - */ - operator fun get(key: String): Any? { - return getControl(key)?.getValue() - } - - /** - * Sets the values of all the controls from the model. - * @param model data model - */ - open fun setData(model: K) { - form.setData(model) - } - - /** - * Sets the values of all controls to null. - */ - open fun clearData() { - form.clearData() - } - - /** - * Returns current data model. - * @return data model - */ - open fun getData(): K { - return form.getData() - } - - /** - * Returns current data model as JSON. - * @return data model as JSON - */ - open fun getDataJson(): Json { - return form.getDataJson() - } - - /** - * Invokes validator function and validates the form. - * @return validation result - */ - open fun validate(): Boolean { - return form.validate() - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun <K> Container.formPanel( - type: FormType? = null, classes: Set<String> = setOf(), - modelFactory: (Map<String, Any?>) -> K - ): FormPanel<K> { - val panel = FormPanel(type, classes, modelFactory) - this.add(panel) - return panel - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt b/src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt deleted file mode 100644 index db9aebc5..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/HelpBlock.kt +++ /dev/null @@ -1,37 +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.form - -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag - -/** - * Helper class for Bootstrap help block element. - * - * @constructor - * @param text the text of the label - * @param rich determines if [text] can contain HTML code - */ -open class HelpBlock(text: String? = null, rich: Boolean = false) : Tag( - TAG.SPAN, text, rich, - classes = setOf("help-block", "small") -) diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt deleted file mode 100644 index c274d999..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt +++ /dev/null @@ -1,207 +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.form.check - -import org.w3c.dom.events.MouseEvent -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.form.BoolFormControl -import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.SnOn - -/** - * Checkbox style options. - */ -enum class CheckBoxStyle(internal val className: String) { - DEFAULT("checkbox-default"), - PRIMARY("checkbox-primary"), - SUCCESS("checkbox-success"), - INFO("checkbox-info"), - WARNING("checkbox-warning"), - DANGER("checkbox-danger"), -} - -/** - * The form field component rendered as HTML *input type="checkbox"*. - * - * @constructor - * @param value selection state - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -open class CheckBox( - value: Boolean = false, label: String? = null, - rich: Boolean = false -) : SimplePanel(setOf("checkbox")), BoolFormControl { - - /** - * The selection state of the checkbox. - */ - override var value - get() = input.value - set(value) { - input.value = value - } - /** - * The value attribute of the generated HTML input element. - * - * This value is placed directly in generated HTML code, while the [value] property is dynamically - * bound to the input selection state. - */ - var startValue - get() = input.startValue - set(value) { - input.startValue = value - } - /** - * The name attribute of the generated HTML input element. - */ - var name - get() = input.name - set(value) { - input.name = value - } - override var disabled - get() = input.disabled - set(value) { - input.disabled = value - } - /** - * The label text bound to the input element. - */ - var label - get() = flabel.text - set(value) { - flabel.text = value - } - /** - * Determines if [label] can contain HTML code. - */ - var rich - get() = flabel.rich - set(value) { - flabel.rich = value - } - /** - * The style (one of Bootstrap standard colors) of the input. - */ - var style: CheckBoxStyle? by refreshOnUpdate() - /** - * Determines if the checkbox is rendered as a circle. - */ - var circled by refreshOnUpdate(false) - /** - * Determines if the checkbox is rendered inline. - */ - var inline by refreshOnUpdate(false) - /** - * The size of the input. - */ - override var size - get() = input.size - set(value) { - input.size = value - } - - private val idc = "kv_form_checkbox_" + counter - final override val input: CheckInput = CheckInput( - CheckInputType.CHECKBOX, value, - setOf("styled") - ).apply { id = idc } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf()) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } - - init { - @Suppress("LeakingThis") - input.eventTarget = this - this.addInternal(input) - this.addInternal(flabel) - this.addInternal(validationInfo) - counter++ - } - - @Suppress("UNCHECKED_CAST") - override fun <T : Widget> setEventListener(block: SnOn<T>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun setEventListener(block: SnOn<Widget>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun removeEventListeners(): Widget { - input.removeEventListeners() - return this - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - style?.let { - cl.add(it.className to true) - } - if (circled) { - cl.add("checkbox-circle" to true) - } - if (inline) { - cl.add("checkbox-inline" to true) - } - if (validatorError != null) { - cl.add("has-error" to true) - } - return cl - } - - /** - * A convenient helper for easy setting onClick event handler. - */ - open fun onClick(handler: CheckBox.(MouseEvent) -> Unit): CheckBox { - this.setEventListener<CheckBox> { - click = { e -> - self.handler(e) - } - } - 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.checkBox( - value: Boolean = false, label: String? = null, - rich: Boolean = false, init: (CheckBox.() -> Unit)? = null - ): CheckBox { - val checkBox = CheckBox(value, label, rich).apply { init?.invoke(this) } - this.add(checkBox) - return checkBox - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt deleted file mode 100644 index a9e7b33d..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt +++ /dev/null @@ -1,170 +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.form.check - -import com.github.snabbdom.VNode -import org.w3c.dom.events.MouseEvent -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.form.InputSize - -/** - * Type of the check input control (checkbox or radio). - */ -enum class CheckInputType(internal val type: String) { - CHECKBOX("checkbox"), - RADIO("radio") -} - -/** - * The basic input component rendered as HTML *input type="checkbox"* or *input type="radio"*. - * - * @constructor - * @param type type of the input control - * @param value selection state - * @param classes a set of CSS class names - */ -open class CheckInput( - type: CheckInputType = CheckInputType.CHECKBOX, value: Boolean = false, - classes: Set<String> = setOf() -) : Widget(classes) { - - init { - this.setInternalEventListener<CheckInput> { - click = { - val v = getElementJQuery()?.prop("checked") as Boolean? - self.value = (v == true) - } - change = { - val v = getElementJQuery()?.prop("checked") as Boolean? - self.value = (v == true) - } - } - } - - /** - * The selection state of the input. - */ - var value by refreshOnUpdate(value, { refreshState() }) - /** - * The value attribute of the generated HTML input element. - * - * This value is placed directly in generated HTML code, while the [value] property is dynamically - * bound to the input selection state. - */ - var startValue by refreshOnUpdate(value, { this.value = it; refresh() }) - /** - * The type of the generated HTML input element. - */ - var type by refreshOnUpdate(type) - /** - * The name attribute of the generated HTML input element. - */ - var name: String? by refreshOnUpdate() - /** - * Determines if the field is disabled. - */ - var disabled by refreshOnUpdate(false) - /** - * The additional String value used for the radio button group. - */ - var extraValue: String? by refreshOnUpdate() - /** - * The size of the input. - */ - var size: InputSize? by refreshOnUpdate() - - override fun render(): VNode { - return render("input") - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - size?.let { - cl.add(it.className to true) - } - return cl - } - - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - sn.add("type" to type.type) - if (startValue) { - sn.add("checked" to "checked") - } - name?.let { - sn.add("name" to it) - } - if (disabled) { - sn.add("disabled" to "disabled") - } - extraValue?.let { - sn.add("value" to it) - } - return sn - } - - override fun afterInsert(node: VNode) { - refreshState() - } - - override fun afterPostpatch(node: VNode) { - refreshState() - } - - private fun refreshState() { - val v = getElementJQuery()?.prop("checked") as Boolean? - if (this.value != v) { - getElementJQuery()?.prop("checked", this.value) - } - } - - /** - * A convenient helper for easy setting onClick event handler. - */ - open fun onClick(handler: CheckInput.(MouseEvent) -> Unit): CheckInput { - this.setEventListener<CheckInput> { - click = { e -> - self.handler(e) - } - } - return this - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.checkInput( - type: CheckInputType = CheckInputType.CHECKBOX, value: Boolean = false, - classes: Set<String> = setOf(), init: (CheckInput.() -> Unit)? = null - ): CheckInput { - val checkInput = CheckInput(type, value, classes).apply { init?.invoke(this) } - this.add(checkInput) - return checkInput - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt deleted file mode 100644 index a4dc851c..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt +++ /dev/null @@ -1,227 +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.form.check - -import org.w3c.dom.events.MouseEvent -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.form.BoolFormControl -import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.SnOn - -/** - * Radio style options. - */ -enum class RadioStyle(internal val className: String) { - DEFAULT("radio-default"), - PRIMARY("radio-primary"), - SUCCESS("radio-success"), - INFO("radio-info"), - WARNING("radio-warning"), - DANGER("radio-danger"), -} - -/** - * The form field component rendered as HTML *input type="radio"*. - * - * @constructor - * @param value selection state - * @param extraValue the additional String value used for the radio button group - * @param name the name attribute of the generated HTML input element - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -open class Radio( - value: Boolean = false, extraValue: String? = null, name: String? = null, label: String? = null, - rich: Boolean = false -) : SimplePanel(), BoolFormControl { - - /** - * The selection state of the radio button. - */ - override var value - get() = input.value - set(value) { - input.value = value - } - /** - * The value attribute of the generated HTML input element. - * - * This value is placed directly in generated HTML code, while the [value] property is dynamically - * bound to the input selection state. - */ - var startValue - get() = input.startValue - set(value) { - input.startValue = value - } - /** - * The additional String value used for the radio button group. - */ - var extraValue - get() = input.extraValue - set(value) { - input.extraValue = value - } - /** - * The name attribute of the generated HTML input element. - */ - var name - get() = input.name - set(value) { - input.name = value - } - override var disabled - get() = input.disabled - set(value) { - input.disabled = value - } - /** - * The label text bound to the input element. - */ - var label - get() = flabel.text - set(value) { - flabel.text = value - } - /** - * Determines if [label] can contain HTML code. - */ - var rich - get() = flabel.rich - set(value) { - flabel.rich = value - } - /** - * The style (one of Bootstrap standard colors) of the input. - */ - var style: RadioStyle? by refreshOnUpdate() - /** - * Determines if the radio button is rendered as a square. - */ - var squared by refreshOnUpdate(false) - /** - * Determines if the radio button is rendered inline. - */ - var inline by refreshOnUpdate(false) - /** - * The size of the input. - */ - override var size - get() = input.size - set(value) { - input.size = value - } - - private val idc = "kv_form_radio_" + counter - final override val input: CheckInput = CheckInput(CheckInputType.RADIO, value).apply { - this.id = idc - this.extraValue = extraValue - this.name = name - } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich, classes = setOf()) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } - - init { - @Suppress("LeakingThis") - input.eventTarget = this.eventTarget ?: this - this.addInternal(input) - this.addInternal(flabel) - this.addInternal(validationInfo) - counter++ - } - - @Suppress("UNCHECKED_CAST") - override fun <T : Widget> setEventListener(block: SnOn<T>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun setEventListener(block: SnOn<Widget>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun removeEventListeners(): Widget { - input.removeEventListeners() - return this - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - if (!squared) { - cl.add("radio" to true) - style?.let { - cl.add(it.className to true) - } - if (inline) { - cl.add("radio-inline" to true) - } - } else { - cl.add("checkbox" to true) - cl.add("kv-radio-checkbox" to true) - style?.let { - cl.add(it.className.replace("radio", "checkbox") to true) - } - if (inline) { - cl.add("checkbox-inline" to true) - } - } - if (validatorError != null) { - cl.add("has-error" to true) - } - return cl - } - - /** - * A convenient helper for easy setting onClick event handler. - */ - open fun onClick(handler: Radio.(MouseEvent) -> Unit): Radio { - this.setEventListener<Radio> { - click = { e -> - self.handler(e) - } - } - 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.radio( - value: Boolean = false, extraValue: String? = null, name: String? = null, label: String? = null, - rich: Boolean = false, init: (Radio.() -> Unit)? = null - ): Radio { - val radio = Radio(value, extraValue, name, label, rich).apply { init?.invoke(this) } - this.add(radio) - return radio - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt deleted file mode 100644 index 8a4a84bd..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt +++ /dev/null @@ -1,171 +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.form.check - -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.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock -import pl.treksoft.kvision.form.InputSize -import pl.treksoft.kvision.form.StringFormControl -import pl.treksoft.kvision.form.select.Select -import pl.treksoft.kvision.panel.SimplePanel - -/** - * The form field component rendered as a group of HTML *input type="radio"* elements with the same name attribute. - * - * The radio group can be populated directly from *options* parameter or manually by adding - * [Radio] components to the container. - * - * @constructor - * @param options an optional list of options (label to value pairs) for the group - * @param value selected option - * @param inline determines if the options are rendered inline - * @param label label text of the options group - * @param rich determines if [label] can contain HTML code - */ -open class RadioGroup( - options: List<StringPair>? = null, value: String? = null, inline: Boolean = false, - label: String? = null, - rich: Boolean = false -) : SimplePanel(setOf("form-group")), StringFormControl { - - /** - * A list of options (label to value pairs) for the group. - */ - var options by refreshOnUpdate(options, { setChildrenFromOptions() }) - - /** - * A value of the selected option. - */ - override var value by refreshOnUpdate(value, { setValueToChildren(it) }) - - /** - * Determines if the options are rendered inline. - */ - var inline by refreshOnUpdate(inline) - - override var disabled - get() = getDisabledFromChildren() - set(value) { - setDisabledToChildren(value) - } - /** - * The label text of the options group. - */ - var label - get() = flabel.text - set(value) { - flabel.text = value - } - /** - * Determines if [label] can contain HTML code. - */ - var rich - get() = flabel.rich - set(value) { - flabel.rich = value - } - override var size: InputSize? = null - - private val idc = "kv_form_radiogroup_" + Select.counter - final override val input = Widget() - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } - - init { - setChildrenFromOptions() - counter++ - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - if (validatorError != null) { - cl.add("has-error" to true) - } - if (inline) { - cl.add("kv-radiogroup-inline" to true) - } else { - cl.add("kv-radiogroup" to true) - } - return cl - } - - private fun setValueToChildren(value: String?) { - val radios = getChildren().filterIsInstance<Radio>() - radios.forEach { it.value = false } - radios.find { - it.extraValue == value - }?.value = true - } - - private fun getDisabledFromChildren(): Boolean { - return getChildren().filterIsInstance<Radio>().firstOrNull()?.disabled ?: false - } - - private fun setDisabledToChildren(disabled: Boolean) { - getChildren().filterIsInstance<Radio>().forEach { it.disabled = disabled } - } - - private fun setChildrenFromOptions() { - super.removeAll() - this.addInternal(flabel) - options?.let { - val tidc = this.idc - val tinline = this.inline - val c = it.map { - Radio(false, extraValue = it.first, label = it.second).apply { - inline = tinline - name = tidc - eventTarget = this@RadioGroup - setEventListener<Radio> { - change = { - this@RadioGroup.value = self.extraValue - } - } - } - } - super.addAll(c) - } - this.addInternal(validationInfo) - } - - companion object { - internal var counter = 0 - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.radioGroup( - options: List<StringPair>? = null, value: String? = null, inline: Boolean = false, - label: String? = null, rich: Boolean = false, init: (RadioGroup.() -> Unit)? = null - ): RadioGroup { - val radioGroup = RadioGroup(options, value, inline, label, rich).apply { init?.invoke(this) } - this.add(radioGroup) - return radioGroup - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt deleted file mode 100644 index 09d2fcdb..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt +++ /dev/null @@ -1,125 +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.form.select - -import pl.treksoft.jquery.JQueryXHR -import pl.treksoft.kvision.KVManager.AJAX_REQUEST_DELAY -import pl.treksoft.kvision.KVManager.KVNULL -import pl.treksoft.kvision.utils.obj - -/** - * HTTP protocol type for the AJAX call. - */ -enum class HttpType(internal val type: String) { - GET("GET"), - POST("POST") -} - -/** - * Data type for the AJAX call. - */ -enum class DataType(internal val type: String) { - JSON("json"), - JSONP("jsonp"), - XML("xml"), - TEXT("text"), - SCRIPT("script") -} - -/** - * Data class for AJAX options. - * - * @constructor - * @param url the url address - * @param preprocessData - * [AjaxBootstrapSelect preprocessOption](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionspreprocessdata) - * option - * @param beforeSend - * [JQuery ajax.beforeSend](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings) option - * @param data - * [JQuery ajax.data](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings) option - * @param httpType - * [JQuery ajax.type](http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings) option - * @param minLength - * [AjaxBootstrapSelect minLength](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsminlength) option - * @param cache - * [AjaxBootstrapSelect cache](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionscache) option - * @param clearOnEmpty - * [AjaxBootstrapSelect clearOnEmpty](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsclearonempty) option - * @param clearOnError - * [AjaxBootstrapSelect clearOnError](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsclearonerror) option - * @param emptyRequest - * [AjaxBootstrapSelect emptyRequest](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsemptyrequest) option - * @param requestDelay - * [AjaxBootstrapSelect requestDelay](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsrequestdelay) option - * @param restoreOnError - * [AjaxBootstrapSelect restoreOnError](https://github.com/truckingsim/Ajax-Bootstrap-Select#optionsrestoreonerror) - * option - */ -data class AjaxOptions( - val url: String, val preprocessData: (dynamic) -> dynamic, val beforeSend: ((JQueryXHR) -> dynamic)? = null, - val data: dynamic = null, val httpType: HttpType = HttpType.GET, - val dataType: DataType = DataType.JSON, val minLength: Int = 0, - val cache: Boolean = true, val clearOnEmpty: Boolean = true, val clearOnError: Boolean = true, - val emptyRequest: Boolean = false, - val requestDelay: Int = AJAX_REQUEST_DELAY, val restoreOnError: Boolean = false -) - -/** - * Convert AjaxOptions to JavaScript JSON object. - * @param emptyOption add an empty position as the first select option - * @return JSON object - */ -fun AjaxOptions.toJs(emptyOption: Boolean): dynamic { - val procData = { data: dynamic -> - val processedData = this.preprocessData(data) - if (emptyOption) { - val ret = mutableListOf(obj { - this.value = KVNULL - this.text = "" - }) - @Suppress("UnsafeCastFromDynamic") - ret.addAll((processedData as Array<dynamic>).asList()) - ret.toTypedArray() - } else { - processedData - } - } - return obj { - this.ajax = obj { - this.url = url - this.type = httpType.type - this.dataType = dataType.type - this.data = data - this.beforeSend = beforeSend - } - this.preprocessData = procData - this.minLength = minLength - this.cache = cache - this.clearOnEmpty = clearOnEmpty - this.clearOnError = clearOnError - this.emptyRequest = emptyRequest - this.preserveSelected = false - this.requestDelay = requestDelay - this.restoreOnError = restoreOnError - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt deleted file mode 100644 index 2e9b5562..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt +++ /dev/null @@ -1,291 +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.form.select - -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.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock -import pl.treksoft.kvision.form.StringFormControl -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.SnOn - -/** - * The form field component for Select control. - * - * The select control can be populated directly from *options* parameter or manually by adding - * [SelectOption] or [SelectOptGroup] components to the container. - * - * @constructor - * @param options an optional list of options (label to value pairs) for the select control - * @param value selected value - * @param multiple allows multiple value selection (multiple values are comma delimited) - * @param ajaxOptions additional options for remote (AJAX) data source - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -@Suppress("TooManyFunctions") -open class Select( - options: List<StringPair>? = null, value: String? = null, - multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, label: String? = null, - rich: Boolean = false -) : SimplePanel(setOf("form-group")), StringFormControl { - - /** - * A list of options (label to value pairs) for the select control. - */ - var options - get() = input.options - set(value) { - input.options = value - } - /** - * A value of the selected option. - */ - override var value - get() = input.value - set(value) { - input.value = value - } - /** - * The name attribute of the generated HTML select element. - */ - var name - get() = input.name - set(value) { - input.name = value - } - /** - * Determines if multiple value selection is allowed. - */ - var multiple - get() = input.multiple - set(value) { - input.multiple = value - } - /** - * Additional options for remote (AJAX) data source. - */ - var ajaxOptions - get() = input.ajaxOptions - set(value) { - input.ajaxOptions = value - } - /** - * Maximal number of selected options. - */ - var maxOptions - get() = input.maxOptions - set(value) { - input.maxOptions = value - } - /** - * Determines if live search is available. - */ - var liveSearch - get() = input.liveSearch - set(value) { - input.liveSearch = value - } - /** - * The placeholder for the select control. - */ - var placeholder - get() = input.placeholder - set(value) { - input.placeholder = value - } - /** - * The style of the select control. - */ - var style - get() = input.style - set(value) { - input.style = value - } - /** - * The width of the select control. - */ - var selectWidth - get() = input.selectWidth - set(value) { - input.selectWidth = value - } - /** - * The width type of the select control. - */ - var selectWidthType - get() = input.selectWidthType - set(value) { - input.selectWidthType = value - } - /** - * Determines if an empty option is automatically generated. - */ - var emptyOption - get() = input.emptyOption - set(value) { - input.emptyOption = value - } - override var disabled - get() = input.disabled - set(value) { - input.disabled = value - } - /** - * Determines if the select is automatically focused. - */ - var autofocus - get() = input.autofocus - set(value) { - input.autofocus = value - } - /** - * The label text bound to the select element. - */ - var label - get() = flabel.text - set(value) { - flabel.text = value - } - /** - * Determines if [label] can contain HTML code. - */ - var rich - get() = flabel.rich - set(value) { - flabel.rich = value - } - override var size - get() = input.size - set(value) { - input.size = value - } - - private val idc = "kv_form_select_" + counter - final override val input: SelectInput = SelectInput( - options, value, multiple, ajaxOptions, - setOf("form-control") - ).apply { id = idc } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } - - init { - @Suppress("LeakingThis") - input.eventTarget = this - this.addInternal(flabel) - this.addInternal(input) - this.addInternal(validationInfo) - counter++ - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - if (validatorError != null) { - cl.add("has-error" to true) - } - return cl - } - - @Suppress("UNCHECKED_CAST") - override fun <T : Widget> setEventListener(block: SnOn<T>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun setEventListener(block: SnOn<Widget>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun removeEventListeners(): Widget { - input.removeEventListeners() - return this - } - - override fun add(child: Component): SimplePanel { - input.add(child) - return this - } - - override fun addAll(children: List<Component>): SimplePanel { - input.addAll(children) - return this - } - - override fun remove(child: Component): SimplePanel { - input.remove(child) - return this - } - - override fun removeAll(): SimplePanel { - input.removeAll() - return this - } - - override fun getChildren(): List<Component> { - return input.getChildren() - } - - /** - * Opens dropdown with options. - */ - open fun showOptions() { - input.showOptions() - } - - /** - * Hides dropdown with options. - */ - open fun hideOptions() { - input.hideOptions() - } - - /** - * Toggles visibility of dropdown with options. - */ - open fun toggleOptions() { - input.toggleOptions() - } - - companion object { - internal var counter = 0 - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.select( - options: List<StringPair>? = null, value: String? = null, - multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, label: String? = null, - rich: Boolean = false, init: (Select.() -> Unit)? = null - ): Select { - val select = Select(options, value, multiple, ajaxOptions, label, rich).apply { init?.invoke(this) } - this.add(select) - return select - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt deleted file mode 100644 index e94d7e2f..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt +++ /dev/null @@ -1,349 +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.form.select - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.KVManager.KVNULL -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.CssSize -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.form.InputSize -import pl.treksoft.kvision.html.ButtonStyle -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.asString -import pl.treksoft.kvision.utils.obj - -/** - * Select width types. See [Bootstrap Select width](http://silviomoreto.github.io/bootstrap-select/examples/#width). - */ -enum class SelectWidthType(internal val value: String) { - AUTO("auto"), - FIT("fit") -} - -/** - * The basic component for Select control. - * - * The select control can be populated directly from *options* parameter or manually by adding - * [SelectOption] or [SelectOptGroup] components to the container. - * - * @constructor - * @param options an optional list of options (label to value pairs) for the select control - * @param value selected value - * @param multiple allows multiple value selection (multiple values are comma delimited) - * @param ajaxOptions additional options for remote (AJAX) data source - * @param classes a set of CSS class names - */ -@Suppress("TooManyFunctions") -open class SelectInput( - options: List<StringPair>? = null, value: String? = null, - multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, - classes: Set<String> = setOf() -) : SimplePanel(classes) { - - /** - * A list of options (label to value pairs) for the select control. - */ - internal var options by refreshOnUpdate(options, { setChildrenFromOptions() }) - /** - * A value of the selected option. - */ - var value by refreshOnUpdate(value, { refreshState() }) - /** - * The name attribute of the generated HTML select element. - */ - var name: String? by refreshOnUpdate() - /** - * Determines if multiple value selection is allowed. - */ - var multiple by refreshOnUpdate(multiple) - /** - * Additional options for remote (AJAX) data source. - */ - var ajaxOptions by refreshOnUpdate(ajaxOptions, { - if (it != null) { - liveSearch = true - } - refresh() - }) - /** - * Maximal number of selected options. - */ - var maxOptions: Int? by refreshOnUpdate() - /** - * Determines if live search is available. - */ - var liveSearch by refreshOnUpdate(false) - /** - * The placeholder for the select control. - */ - var placeholder: String? by refreshOnUpdate() - /** - * The style of the select control. - */ - var style: ButtonStyle? by refreshOnUpdate() - /** - * The width of the select control. - */ - var selectWidth: CssSize? by refreshOnUpdate() - /** - * The width type of the select control. - */ - var selectWidthType: SelectWidthType? by refreshOnUpdate() - /** - * Determines if an empty option is automatically generated. - */ - var emptyOption by refreshOnUpdate(false, { setChildrenFromOptions() }) - /** - * Determines if the field is disabled. - */ - var disabled by refreshOnUpdate(false) - /** - * Determines if the select is automatically focused. - */ - var autofocus: Boolean? by refreshOnUpdate() - /** - * The size of the input. - */ - var size: InputSize? by refreshOnUpdate() - - init { - setChildrenFromOptions() - this.setInternalEventListener<SelectInput> { - change = { - val v = getElementJQuery()?.`val`() - self.value = v?.let { - calculateValue(it) - } - } - } - } - - private fun calculateValue(v: Any): String? { - return if (this.multiple) { - @Suppress("UNCHECKED_CAST") - val arr = v as? Array<String> - if (arr != null && arr.isNotEmpty()) { - arr.joinToString() - } else { - null - } - } else { - val vs = v as String - if (KVNULL == vs || vs.isEmpty()) { - null - } else { - vs - } - } - } - - override fun render(): VNode { - return render("select", childrenVNodes()) - } - - override fun add(child: Component): SimplePanel { - super.add(child) - refreshSelectInput() - return this - } - - override fun addAll(children: List<Component>): SimplePanel { - super.addAll(children) - refreshSelectInput() - return this - } - - override fun remove(child: Component): SimplePanel { - super.remove(child) - refreshSelectInput() - return this - } - - override fun removeAll(): SimplePanel { - super.removeAll() - refreshSelectInput() - return this - } - - private fun setChildrenFromOptions() { - if (ajaxOptions == null) { - super.removeAll() - if (emptyOption) { - super.add(SelectOption(KVNULL, "")) - } - options?.let { - val c = it.map { - SelectOption(it.first, it.second) - } - super.addAll(c) - } - } - this.refreshSelectInput() - } - - /** - * Opens dropdown with options. - */ - open fun showOptions() { - getElementJQueryD()?.selectpicker("show") - } - - /** - * Hides dropdown with options. - */ - open fun hideOptions() { - getElementJQueryD()?.selectpicker("hide") - } - - /** - * Toggles visibility of dropdown with options. - */ - open fun toggleOptions() { - getElementJQueryD()?.selectpicker("toggle") - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - cl.add("selectpicker" to true) - size?.let { - cl.add(it.className to true) - } - return cl - } - - private fun refreshSelectInput() { - getElementJQueryD()?.selectpicker("refresh") - refreshState() - } - - @Suppress("ComplexMethod") - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - name?.let { - sn.add("name" to it) - } - if (multiple) { - sn.add("multiple" to "multiple") - } - maxOptions?.let { - sn.add("data-max-options" to "" + it) - } - if (liveSearch) { - sn.add("data-live-search" to "true") - } - placeholder?.let { - sn.add("title" to it) - } - autofocus?.let { - if (it) { - sn.add("autofocus" to "autofocus") - } - } - if (disabled) { - sn.add("disabled" to "disabled") - } - val btnStyle = style?.className ?: "btn-default" - when (size) { - InputSize.LARGE -> { - sn.add("data-style" to "$btnStyle btn-lg") - } - InputSize.SMALL -> { - sn.add("data-style" to "$btnStyle btn-sm") - } - else -> { - sn.add("data-style" to btnStyle) - } - } - selectWidthType?.let { - sn.add("data-width" to it.value) - } ?: selectWidth?.let { - sn.add("data-width" to it.asString()) - } - return sn - } - - @Suppress("UnsafeCastFromDynamic") - override fun afterInsert(node: VNode) { - ajaxOptions?.let { - getElementJQueryD()?.selectpicker("render").ajaxSelectPicker(it.toJs(emptyOption)) - } ?: getElementJQueryD()?.selectpicker("render") - - this.getElementJQuery()?.on("show.bs.select", { e, _ -> - this.dispatchEvent("showBsSelect", obj { detail = e }) - }) - this.getElementJQuery()?.on("shown.bs.select", { e, _ -> - this.dispatchEvent("shownBsSelect", obj { detail = e }) - }) - this.getElementJQuery()?.on("hide.bs.select", { e, _ -> - this.dispatchEvent("hideBsSelect", obj { detail = e }) - }) - this.getElementJQuery()?.on("hidden.bs.select", { e, _ -> - this.dispatchEvent("hiddenBsSelect", obj { detail = e }) - }) - this.getElementJQuery()?.on("loaded.bs.select", { e, _ -> - this.dispatchEvent("loadedBsSelect", obj { detail = e }) - }) - this.getElementJQuery()?.on("rendered.bs.select", { e, _ -> - this.dispatchEvent("renderedBsSelect", obj { detail = e }) - }) - this.getElementJQuery()?.on("refreshed.bs.select", { e, _ -> - this.dispatchEvent("refreshedBsSelect", obj { detail = e }) - }) - this.getElementJQueryD()?.on("changed.bs.select", { e, cIndex: Int -> - e["clickedIndex"] = cIndex - this.dispatchEvent("changedBsSelect", obj { detail = e }) - }) - refreshState() - } - - @Suppress("UnsafeCastFromDynamic") - private fun refreshState() { - value?.let { - if (multiple) { - getElementJQueryD()?.selectpicker("val", it.split(",").toTypedArray()) - } else { - getElementJQueryD()?.selectpicker("val", it) - } - } ?: getElementJQueryD()?.selectpicker("val", null) - } - - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.selectInput( - options: List<StringPair>? = null, value: String? = null, - multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, - classes: Set<String> = setOf(), init: (SelectInput.() -> Unit)? = null - ): SelectInput { - val selectInput = SelectInput(options, value, multiple, ajaxOptions, classes).apply { init?.invoke(this) } - this.add(selectInput) - return selectInput - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt deleted file mode 100644 index 3b523314..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt +++ /dev/null @@ -1,91 +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.form.select - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.panel.SimplePanel - -/** - * The helper container for adding option groups to [Select]. - * - * The option group can be populated directly from *options* parameter or manually by adding - * [SelectOption] components to the container. - * - * @constructor - * @param label the label of the group - * @param options an optional list of options (label to value pairs) for the group - * @param maxOptions maximal number of selected options in the group - * @param disabled renders a disabled group - * @param classes a set of CSS class names - */ -open class SelectOptGroup( - label: String, options: List<StringPair>? = null, maxOptions: Int? = null, - disabled: Boolean = false, classes: Set<String> = setOf() -) : SimplePanel(classes) { - /** - * A label for the group. - */ - var label by refreshOnUpdate(label) - /** - * A list of options (label to value pairs) for the group. - */ - var options by refreshOnUpdate(options, { setChildrenFromOptions() }) - /** - * Maximal number of selected options in the group. - */ - var maxOptions by refreshOnUpdate(maxOptions) - /** - * Determines if the group is disabled. - */ - var disabled by refreshOnUpdate(disabled) - - init { - setChildrenFromOptions() - } - - override fun render(): VNode { - return render("optgroup", childrenVNodes()) - } - - private fun setChildrenFromOptions() { - this.removeAll() - options?.let { - val c = it.map { - SelectOption(it.first, it.second) - } - this.addAll(c) - } - } - - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - sn.add("label" to label) - maxOptions?.let { - sn.add("data-max-options" to "" + it) - } - if (disabled) { - sn.add("disabled" to "disabled") - } - return sn - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt deleted file mode 100644 index 5cd23582..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt +++ /dev/null @@ -1,103 +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.form.select - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.core.Widget - -/** - * The helper component for adding options to [Select] or [SelectOptGroup]. - * - * @constructor - * @param value the value of the option - * @param label the label of the option - * @param subtext the small subtext after the label of the option - * @param icon the icon before the label of the option - * @param divider renders this option as a divider - * @param disabled renders a disabled option - * @param classes a set of CSS class names - */ -open class SelectOption( - value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, - divider: Boolean = false, disabled: Boolean = false, - classes: Set<String> = setOf() -) : Widget(classes) { - - /** - * The value of the option. - */ - var value by refreshOnUpdate(value) - /** - * The label of the option. - */ - var label by refreshOnUpdate(label) - /** - * The subtext after the label of the option. - */ - var subtext by refreshOnUpdate(subtext) - /** - * The icon before the label of the option. - */ - var icon by refreshOnUpdate(icon) - /** - * Determines if the option should be rendered as divider. - */ - var divider by refreshOnUpdate(divider) - /** - * Determines if the option should be disabled. - */ - var disabled by refreshOnUpdate(disabled) - - override fun render(): VNode { - return if (!divider) { - render("option", arrayOf(label ?: value)) - } else { - render("option") - } - } - - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - if (!divider) { - value?.let { - sn.add("value" to it) - } - subtext?.let { - sn.add("data-subtext" to it) - } - icon?.let { - if (it.startsWith("fa-")) { - sn.add("data-icon" to "fa $it") - } else { - sn.add("data-icon" to "glyphicon-$it") - } - } - if (disabled) { - sn.add("disabled" to "disabled") - } - } else { - sn.add("data-divider" to "true") - } - return sn - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt b/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt deleted file mode 100644 index 7a6a535d..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt +++ /dev/null @@ -1,262 +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.form.spinner - -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.NumberFormControl -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.SnOn - -/** - * The form field component for spinner control. - * - * @constructor - * @param value spinner value - * @param min minimal value (default 0) - * @param max maximal value (default 100) - * @param step step value (default 1) - * @param decimals number of decimal digits (default 0) - * @param buttonsType spinner buttons type - * @param forceType spinner force rounding type - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -open class Spinner( - value: Number? = null, min: Int = 0, max: Int = DEFAULT_MAX, step: Double = DEFAULT_STEP, - decimals: Int = 0, buttonsType: ButtonsType = ButtonsType.VERTICAL, - forceType: ForceType = ForceType.NONE, label: String? = null, - rich: Boolean = false -) : SimplePanel(setOf("form-group")), NumberFormControl { - - /** - * Spinner value. - */ - override var value - get() = input.value - set(value) { - input.value = value - } - /** - * The value attribute of the generated HTML input element. - * - * This value is placed directly in generated HTML code, while the [value] property is dynamically - * bound to the spinner input value. - */ - var startValue - get() = input.startValue - set(value) { - input.startValue = value - } - /** - * Minimal value. - */ - var min - get() = input.min - set(value) { - input.min = value - } - /** - * Maximal value. - */ - var max - get() = input.max - set(value) { - input.max = value - } - /** - * Step value. - */ - var step - get() = input.step - set(value) { - input.step = value - } - /** - * Number of decimal digits value. - */ - var decimals - get() = input.decimals - set(value) { - input.decimals = value - } - /** - * Spinner buttons type. - */ - var buttonsType - get() = input.buttonsType - set(value) { - input.buttonsType = value - } - /** - * Spinner force rounding type. - */ - var forceType - get() = input.forceType - set(value) { - input.forceType = value - } - /** - * The placeholder for the spinner input. - */ - var placeholder - get() = input.placeholder - set(value) { - input.placeholder = value - } - /** - * The name attribute of the generated HTML input element. - */ - var name - get() = input.name - set(value) { - input.name = value - } - override var disabled - get() = input.disabled - set(value) { - input.disabled = value - } - /** - * Determines if the spinner is automatically focused. - */ - var autofocus - get() = input.autofocus - set(value) { - input.autofocus = value - } - /** - * Determines if the spinner is read-only. - */ - var readonly - get() = input.readonly - set(value) { - input.readonly = value - } - /** - * The label text bound to the spinner input element. - */ - var label - get() = flabel.text - set(value) { - flabel.text = value - } - /** - * Determines if [label] can contain HTML code. - */ - var rich - get() = flabel.rich - set(value) { - flabel.rich = value - } - override var size - get() = input.size - set(value) { - input.size = value - } - - protected val idc = "kv_form_spinner_" + counter - final override val input: SpinnerInput = SpinnerInput(value, min, max, step, decimals, buttonsType, forceType) - .apply { id = idc } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } - - init { - @Suppress("LeakingThis") - input.eventTarget = this - this.addInternal(flabel) - this.addInternal(input) - this.addInternal(validationInfo) - counter++ - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - if (validatorError != null) { - cl.add("has-error" to true) - } - return cl - } - - @Suppress("UNCHECKED_CAST") - override fun <T : Widget> setEventListener(block: SnOn<T>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun setEventListener(block: SnOn<Widget>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun removeEventListeners(): Widget { - input.removeEventListeners() - return this - } - - override fun getValueAsString(): String? { - return input.getValueAsString() - } - - /** - * Change value in plus. - */ - open fun spinUp(): Spinner { - input.spinUp() - return this - } - - /** - * Change value in minus. - */ - open fun spinDown(): Spinner { - input.spinDown() - 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.spinner( - value: Number? = null, min: Int = 0, max: Int = DEFAULT_MAX, step: Double = DEFAULT_STEP, - decimals: Int = 0, buttonsType: ButtonsType = ButtonsType.VERTICAL, - forceType: ForceType = ForceType.NONE, label: String? = null, - rich: Boolean = false, init: (Spinner.() -> Unit)? = null - ): Spinner { - val spinner = Spinner(value, min, max, step, decimals, buttonsType, forceType, label, rich).apply { - init?.invoke( - this - ) - } - this.add(spinner) - return spinner - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt deleted file mode 100644 index a0da7999..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt +++ /dev/null @@ -1,307 +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.form.spinner - -import com.github.snabbdom.VNode -import pl.treksoft.jquery.JQuery -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.form.InputSize -import pl.treksoft.kvision.utils.obj - -/** - * Spinner buttons layout types. - */ -enum class ButtonsType { - NONE, - HORIZONTAL, - VERTICAL -} - -/** - * Spinner force rounding types. - */ -enum class ForceType(internal val value: String) { - NONE("none"), - ROUND("round"), - FLOOR("floor"), - CEIL("cail") -} - -internal const val DEFAULT_STEP = 1.0 -internal const val DEFAULT_MAX = 100 - -/** - * The basic component for spinner control. - * - * @constructor - * @param value spinner value - * @param min minimal value (default 0) - * @param max maximal value (default 100) - * @param step step value (default 1) - * @param decimals number of decimal digits (default 0) - * @param buttonsType spinner buttons type - * @param forceType spinner force rounding type - * @param classes a set of CSS class names - */ -@Suppress("TooManyFunctions") -open class SpinnerInput( - value: Number? = null, min: Int = 0, max: Int = DEFAULT_MAX, step: Double = DEFAULT_STEP, - decimals: Int = 0, buttonsType: ButtonsType = ButtonsType.VERTICAL, - forceType: ForceType = ForceType.NONE, - classes: Set<String> = setOf() -) : Widget(classes + "form-control") { - - init { - this.addSurroundingCssClass("input-group") - if (buttonsType == ButtonsType.NONE) { - this.addSurroundingCssClass("kv-spinner-btn-none") - } else { - this.removeSurroundingCssClass("kv-spinner-btn-none") - } - if (buttonsType == ButtonsType.VERTICAL) { - this.addSurroundingCssClass("kv-spinner-btn-vertical") - } else { - this.removeSurroundingCssClass("kv-spinner-btn-vertical") - } - this.surroundingSpan = true - this.refreshSpinner() - this.setInternalEventListener<SpinnerInput> { - change = { - self.changeValue() - } - } - } - - /** - * Spinner value. - */ - var value by refreshOnUpdate(value, { refreshState() }) - /** - * The value attribute of the generated HTML input element. - * - * This value is placed directly in generated HTML code, while the [value] property is dynamically - * bound to the spinner input value. - */ - var startValue by refreshOnUpdate(value, { this.value = it; refresh() }) - /** - * Minimal value. - */ - var min by refreshOnUpdate(min, { refreshSpinner() }) - /** - * Maximal value. - */ - var max by refreshOnUpdate(max, { refreshSpinner() }) - /** - * Step value. - */ - var step by refreshOnUpdate(step, { refreshSpinner() }) - /** - * Number of decimal digits value. - */ - var decimals by refreshOnUpdate(decimals, { refreshSpinner() }) - /** - * Spinner buttons type. - */ - var buttonsType by refreshOnUpdate(buttonsType, { refreshSpinner() }) - /** - * Spinner force rounding type. - */ - var forceType by refreshOnUpdate(forceType, { refreshSpinner() }) - /** - * The placeholder for the spinner input. - */ - var placeholder: String? by refreshOnUpdate() - /** - * The name attribute of the generated HTML input element. - */ - var name: String? by refreshOnUpdate() - /** - * Determines if the field is disabled. - */ - var disabled by refreshOnUpdate(false) - /** - * Determines if the spinner is automatically focused. - */ - var autofocus: Boolean? by refreshOnUpdate() - /** - * Determines if the spinner is read-only. - */ - var readonly: Boolean? by refreshOnUpdate() - /** - * The size of the input. - */ - var size: InputSize? by refreshOnUpdate() - - private var siblings: JQuery? = null - - override fun render(): VNode { - return render("input") - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - size?.let { - cl.add(it.className to true) - } - return cl - } - - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - sn.add("type" to "text") - startValue?.let { - sn.add("value" to it.toString()) - } - placeholder?.let { - sn.add("placeholder" to it) - } - name?.let { - sn.add("name" to it) - } - autofocus?.let { - if (it) { - sn.add("autofocus" to "autofocus") - } - } - readonly?.let { - if (it) { - sn.add("readonly" to "readonly") - } - } - if (disabled) { - sn.add("disabled" to "disabled") - value?.let { - sn.add("value" to it.toString()) - } - } - return sn - } - - protected open fun changeValue() { - val v = getElementJQuery()?.`val`() as String? - if (v != null && v.isNotEmpty()) { - this.value = v.toDoubleOrNull() - } else { - this.value = null - } - } - - @Suppress("UnsafeCastFromDynamic") - override fun afterInsert(node: VNode) { - getElementJQueryD()?.TouchSpin(getSettingsObj()) - siblings = getElementJQuery()?.parent(".bootstrap-touchspin")?.children("span") - size?.let { - siblings?.find("button")?.addClass(it.className) - } - this.getElementJQuery()?.on("change", { e, _ -> - if (e.asDynamic().isTrigger != null) { - val event = org.w3c.dom.events.Event("change") - this.getElement()?.dispatchEvent(event) - } - }) - this.getElementJQuery()?.on("touchspin.on.min", { e, _ -> - this.dispatchEvent("onMinBsSpinner", obj { detail = e }) - }) - this.getElementJQuery()?.on("touchspin.on.max", { e, _ -> - this.dispatchEvent("onMaxBsSpinner", obj { detail = e }) - }) - refreshState() - } - - override fun afterDestroy() { - siblings?.remove() - siblings = null - } - - /** - * Returns the value of the spinner as a String. - * @return value as a String - */ - fun getValueAsString(): String? { - return value?.toString() - } - - /** - * Change value in plus. - */ - fun spinUp(): SpinnerInput { - getElementJQueryD()?.trigger("touchspin.uponce") - return this - } - - /** - * Change value in minus. - */ - fun spinDown(): SpinnerInput { - getElementJQueryD()?.trigger("touchspin.downonce") - return this - } - - private fun refreshState() { - value?.let { - getElementJQuery()?.`val`(it.toString()) - } ?: getElementJQueryD()?.`val`(null) - } - - private fun refreshSpinner() { - getElementJQueryD()?.trigger("touchspin.updatesettings", getSettingsObj()) - } - - private fun getSettingsObj(): dynamic { - val verticalbuttons = buttonsType == ButtonsType.VERTICAL || buttonsType == ButtonsType.NONE - return obj { - this.min = min - this.max = max - this.step = step - this.decimals = decimals - this.verticalbuttons = verticalbuttons - this.forcestepdivisibility = forceType.value - } - } - - companion object { - internal var counter = 0 - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.spinnerInput( - value: Number? = null, min: Int = 0, max: Int = DEFAULT_MAX, step: Double = DEFAULT_STEP, - decimals: Int = 0, buttonsType: ButtonsType = ButtonsType.VERTICAL, - forceType: ForceType = ForceType.NONE, classes: Set<String> = setOf(), - init: (SpinnerInput.() -> Unit)? = null - ): SpinnerInput { - val spinnerInput = SpinnerInput(value, min, max, step, decimals, buttonsType, forceType, classes).apply { - init?.invoke( - this - ) - } - this.add(spinnerInput) - return spinnerInput - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt deleted file mode 100644 index 26a88f1e..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt +++ /dev/null @@ -1,183 +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.form.text - -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.form.FieldLabel -import pl.treksoft.kvision.form.HelpBlock -import pl.treksoft.kvision.form.StringFormControl -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.SnOn - -/** - * Base class for form field text components. - * - * @constructor - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -abstract class AbstractText(label: String? = null, rich: Boolean = false) : - SimplePanel(setOf("form-group")), StringFormControl { - - /** - * Text input value. - */ - override var value - get() = input.value - set(value) { - input.value = value - } - /** - * The value attribute of the generated HTML input element. - * - * This value is placed directly in generated HTML code, while the [value] property is dynamically - * bound to the text input value. - */ - var startValue - get() = input.startValue - set(value) { - input.startValue = value - } - /** - * The placeholder for the text input. - */ - var placeholder - get() = input.placeholder - set(value) { - input.placeholder = value - } - /** - * The name attribute of the generated HTML input element. - */ - var name - get() = input.name - set(value) { - input.name = value - } - /** - * Maximal length of the text input value. - */ - var maxlength - get() = input.maxlength - set(value) { - input.maxlength = value - } - override var disabled - get() = input.disabled - set(value) { - input.disabled = value - } - /** - * Determines if the text input is automatically focused. - */ - var autofocus - get() = input.autofocus - set(value) { - input.autofocus = value - } - /** - * Determines if the text input is read-only. - */ - var readonly - get() = input.readonly - set(value) { - input.readonly = value - } - /** - * The label text bound to the text input element. - */ - var label - get() = flabel.text - set(value) { - flabel.text = value - } - /** - * Determines if [label] can contain HTML code. - */ - var rich - get() = flabel.rich - set(value) { - flabel.rich = value - } - override var size - get() = input.size - set(value) { - input.size = value - } - - /** - * @suppress - * Internal property - */ - protected val idc = "kv_form_text_" + counter - abstract override val input: AbstractTextInput - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } - - init { - this.addInternal(flabel) - counter++ - } - - companion object { - internal var counter = 0 - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - if (validatorError != null) { - cl.add("has-error" to true) - } - return cl - } - - @Suppress("UNCHECKED_CAST") - override fun <T : Widget> setEventListener(block: SnOn<T>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun setEventListener(block: SnOn<Widget>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun removeEventListeners(): Widget { - input.removeEventListeners() - return this - } - - /** - * Makes the input element focused. - */ - open fun focus() { - input.focus() - } - - /** - * Makes the input element blur. - */ - open fun blur() { - input.blur() - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt deleted file mode 100644 index 5f4a243d..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt +++ /dev/null @@ -1,172 +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.form.text - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.form.InputSize - -/** - * Base class for basic text components. - * - * @constructor - * @param value text input value - * @param classes a set of CSS class names - */ -abstract class AbstractTextInput( - value: String? = null, - classes: Set<String> = setOf() -) : Widget(classes) { - - init { - this.setInternalEventListener<AbstractTextInput> { - input = { - self.changeValue() - } - } - } - - /** - * Text input value. - */ - var value by refreshOnUpdate(value, { refreshState() }) - /** - * The value attribute of the generated HTML input element. - * - * This value is placed directly in generated HTML code, while the [value] property is dynamically - * bound to the text input value. - */ - var startValue by refreshOnUpdate(value, { this.value = it; refresh() }) - /** - * The placeholder for the text input. - */ - var placeholder: String? by refreshOnUpdate() - /** - * The name attribute of the generated HTML input element. - */ - var name: String? by refreshOnUpdate() - /** - * Maximal length of the text input value. - */ - var maxlength: Int? by refreshOnUpdate() - /** - * Determines if the field is disabled. - */ - var disabled by refreshOnUpdate(false) - /** - * Determines if the text input is automatically focused. - */ - var autofocus: Boolean? by refreshOnUpdate() - /** - * Determines if the text input is read-only. - */ - var readonly: Boolean? by refreshOnUpdate() - /** - * The size of the input. - */ - var size: InputSize? by refreshOnUpdate() - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - size?.let { - cl.add(it.className to true) - } - return cl - } - - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - placeholder?.let { - sn.add("placeholder" to it) - } - name?.let { - sn.add("name" to it) - } - autofocus?.let { - if (it) { - sn.add("autofocus" to "autofocus") - } - } - maxlength?.let { - sn.add("maxlength" to ("" + it)) - } - readonly?.let { - if (it) { - sn.add("readonly" to "readonly") - } - } - if (disabled) { - sn.add("disabled" to "disabled") - } - return sn - } - - override fun afterInsert(node: VNode) { - refreshState() - } - - override fun afterPostpatch(node: VNode) { - refreshState() - } - - /** - * @suppress - * Internal function - */ - protected open fun refreshState() { - val v = (getElementJQuery()?.`val`() as? String) - if (v != value && !(v.isNullOrEmpty() && value == null)) { - value?.let { - getElementJQuery()?.`val`(it) - } ?: getElementJQueryD()?.`val`(null) - } - } - - /** - * @suppress - * Internal function - */ - protected open fun changeValue() { - val v = getElementJQuery()?.`val`() as String? - if (v != null && v.isNotEmpty()) { - this.value = v - } else { - this.value = null - } - } - - /** - * Makes the input element focused. - */ - open fun focus() { - getElementJQuery()?.focus() - } - - /** - * Makes the input element blur. - */ - open fun blur() { - getElementJQuery()?.blur() - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/Password.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/Password.kt deleted file mode 100644 index 995243c9..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/Password.kt +++ /dev/null @@ -1,52 +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.form.text - -import pl.treksoft.kvision.core.Container - -/** - * Form field password component. - * - * @constructor - * @param value text input value - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -open class Password(value: String? = null, label: String? = null, rich: Boolean = false) : Text( - TextInputType.PASSWORD, - value, label, rich -) { - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.password( - value: String? = null, label: String? = null, rich: Boolean = false, init: (Password.() -> Unit)? = null - ): Password { - val password = Password(value, label, rich).apply { init?.invoke(this) } - this.add(password) - return password - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt deleted file mode 100644 index 953fec90..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/RichText.kt +++ /dev/null @@ -1,71 +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.form.text - -import pl.treksoft.kvision.core.Container - -/** - * Form field rich text component. - * - * @constructor - * @param value text input value - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -open class RichText( - value: String? = null, - label: String? = null, rich: Boolean = false -) : AbstractText(label, rich) { - - /** - * Rich input control height. - */ - var inputHeight - get() = input.height - set(value) { - input.height = value - } - - final override val input: RichTextInput = RichTextInput(value).apply { id = idc } - - init { - @Suppress("LeakingThis") - input.eventTarget = this - this.addInternal(input) - this.addInternal(validationInfo) - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.richText( - value: String? = null, label: String? = null, rich: Boolean = false, init: (RichText.() -> Unit)? = null - ): RichText { - val richText = RichText(value, label, rich).apply { init?.invoke(this) } - this.add(richText) - return richText - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt deleted file mode 100644 index de8bb320..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt +++ /dev/null @@ -1,127 +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.form.text - -import com.github.snabbdom.VNode -import pl.treksoft.jquery.jQuery -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringPair -import kotlin.browser.document - -/** - * Basic rich text component. - * - * @constructor - * @param value text input value - * @param classes a set of CSS class names - */ -open class RichTextInput(value: String? = null, classes: Set<String> = setOf()) : - AbstractTextInput(value, classes + "form-control" + "trix-control") { - - private var trixId: String? = null - - override fun render(): VNode { - return render("trix-editor") - } - - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - placeholder?.let { - sn.add("placeholder" to it) - } - name?.let { - sn.add("name" to it) - } - autofocus?.let { - if (it) { - sn.add("autofocus" to "autofocus") - } - } - if (disabled) { - sn.add("disabled" to "disabled") - } - return sn - } - - @Suppress("UnsafeCastFromDynamic") - override fun afterInsert(node: VNode) { - if (this.disabled || this.readonly == true) { - this.getElementJQuery()?.removeAttr("contenteditable") - } else { - this.getElementJQuery()?.on("trix-change", { _, _ -> - if (trixId != null) { - val v = document.getElementById("trix-input-" + trixId)?.let { jQuery(it).`val`() as String? } - value = if (v != null && v.isNotEmpty()) { - v - } else { - null - } - val event = org.w3c.dom.events.Event("change") - this.getElement()?.dispatchEvent(event) - } - }) - } - this.getElementJQuery()?.on("trix-initialize", { _, _ -> - trixId = this.getElementJQuery()?.attr("trix-id") - value?.let { - this.getElement().asDynamic().editor.loadHTML(it) - } - }) - this.getElementJQuery()?.on("trix-file-accept", { e, _ -> e.preventDefault() }) - } - - override fun afterDestroy() { - document.getElementById("trix-input-" + trixId)?.let { jQuery(it).remove() } - document.getElementById("trix-toolbar-" + trixId)?.let { jQuery(it).remove() } - trixId = null - } - - @Suppress("UnsafeCastFromDynamic") - override fun refreshState() { - val v = document.getElementById("trix-input-" + trixId)?.let { jQuery(it).`val`() as String? } - if (value != v) { - val editor = this.getElement().asDynamic().editor - value?.let { - editor.loadHTML(it) - } ?: editor.loadHTML("") - } - } - - override fun changeValue() { - // disabled parent class functionality - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.richTextInput( - value: String? = null, classes: Set<String> = setOf(), init: (RichTextInput.() -> Unit)? = null - ): RichTextInput { - val richTextInput = RichTextInput(value, classes).apply { init?.invoke(this) } - this.add(richTextInput) - return richTextInput - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt deleted file mode 100644 index fd53adff..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/Text.kt +++ /dev/null @@ -1,81 +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.form.text - -import pl.treksoft.kvision.core.Container - -/** - * Form field text component. - * - * @constructor - * @param type text input type (default "text") - * @param value text input value - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -open class Text( - type: TextInputType = TextInputType.TEXT, value: String? = null, - label: String? = null, rich: Boolean = false -) : AbstractText(label, rich) { - - /** - * Text input type. - */ - var type - get() = input.type - set(value) { - input.type = value - } - /** - * Determines if autocomplete is enabled for the input element. - */ - var autocomplete - get() = input.autocomplete - set(value) { - input.autocomplete = value - } - - final override val input: TextInput = TextInput(type, value).apply { id = idc } - - init { - @Suppress("LeakingThis") - input.eventTarget = this - this.addInternal(input) - this.addInternal(validationInfo) - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.text( - type: TextInputType = TextInputType.TEXT, value: String? = null, - label: String? = null, rich: Boolean = false, init: (Text.() -> Unit)? = null - ): Text { - val text = Text(type, value, label, rich).apply { init?.invoke(this) } - this.add(text) - return text - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt deleted file mode 100644 index 58f63028..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/TextArea.kt +++ /dev/null @@ -1,90 +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.form.text - -import pl.treksoft.kvision.core.Container - -/** - * Form field textarea component. - * - * @constructor - * @param cols number of columns - * @param rows number of rows - * @param value text input value - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -open class TextArea( - cols: Int? = null, rows: Int? = null, value: String? = null, - label: String? = null, rich: Boolean = false -) : AbstractText(label, rich) { - - /** - * Number of columns. - */ - var cols - get() = input.cols - set(value) { - input.cols = value - } - /** - * Number of rows. - */ - var rows - get() = input.rows - set(value) { - input.rows = value - } - /** - * Determines if hard wrapping is enabled for the textarea element. - */ - var wrapHard - get() = input.wrapHard - set(value) { - input.wrapHard = value - } - - final override val input: TextAreaInput = TextAreaInput(cols, rows, value).apply { id = idc } - - init { - @Suppress("LeakingThis") - input.eventTarget = this - this.addInternal(input) - this.addInternal(validationInfo) - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.textArea( - cols: Int? = null, rows: Int? = null, value: String? = null, - label: String? = null, rich: Boolean = false, init: (TextArea.() -> Unit)? = null - ): TextArea { - val textArea = TextArea(cols, rows, value, label, rich).apply { init?.invoke(this) } - this.add(textArea) - return textArea - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt deleted file mode 100644 index 9fc89544..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt +++ /dev/null @@ -1,88 +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.form.text - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringPair - -/** - * Basic textarea component. - * - * @constructor - * @param cols number of columns - * @param rows number of rows - * @param value text input value - * @param classes a set of CSS class names - */ -open class TextAreaInput(cols: Int? = null, rows: Int? = null, value: String? = null, classes: Set<String> = setOf()) : - AbstractTextInput(value, classes + "form-control") { - - /** - * Number of columns. - */ - var cols by refreshOnUpdate(cols) - /** - * Number of rows. - */ - var rows by refreshOnUpdate(rows) - /** - * Determines if hard wrapping is enabled for the textarea element. - */ - var wrapHard by refreshOnUpdate(false) - - override fun render(): VNode { - return startValue?.let { - render("textarea", arrayOf(it)) - } ?: render("textarea") - } - - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - cols?.let { - sn.add("cols" to ("" + it)) - } - rows?.let { - sn.add("rows" to ("" + it)) - } - if (wrapHard) { - sn.add("wrap" to "hard") - } - return sn - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.textAreaInput( - cols: Int? = null, rows: Int? = null, value: String? = null, classes: Set<String> = setOf(), - init: (TextAreaInput.() -> Unit)? = null - ): TextAreaInput { - val textAreaInput = TextAreaInput(cols, rows, value, classes).apply { init?.invoke(this) } - this.add(textAreaInput) - return textAreaInput - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/TextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/TextInput.kt deleted file mode 100644 index bc6e178d..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/TextInput.kt +++ /dev/null @@ -1,96 +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.form.text - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringPair - -/** - * Text input types. - */ -enum class TextInputType(internal val type: String) { - TEXT("text"), - PASSWORD("password"), - EMAIL("email"), - TEL("tel"), - COLOR("color"), - SEARCH("search"), - URL("url") -} - -/** - * Basic text component. - * - * @constructor - * @param type text input type (default "text") - * @param value text input value - * @param classes a set of CSS class names - */ -open class TextInput(type: TextInputType = TextInputType.TEXT, value: String? = null, classes: Set<String> = setOf()) : - AbstractTextInput(value, classes + "form-control") { - - /** - * Text input type. - */ - var type by refreshOnUpdate(type) - /** - * Determines if autocomplete is enabled for the input element. - */ - var autocomplete: Boolean? by refreshOnUpdate() - - override fun render(): VNode { - return render("input") - } - - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - sn.add("type" to type.type) - startValue?.let { - sn.add("value" to it) - } - autocomplete?.let { - if (it) { - sn.add("autocomplete" to "on") - } else { - sn.add("autocomplete" to "off") - } - } - return sn - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.textInput( - type: TextInputType = TextInputType.TEXT, value: String? = null, classes: Set<String> = setOf(), - init: (TextInput.() -> Unit)? = null - ): TextInput { - val textInput = TextInput(type, value, classes).apply { init?.invoke(this) } - this.add(textInput) - return textInput - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt b/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt deleted file mode 100644 index 29cb664d..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt +++ /dev/null @@ -1,252 +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.form.time - -import pl.treksoft.kvision.core.Container -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.panel.SimplePanel -import pl.treksoft.kvision.utils.SnOn -import kotlin.js.Date - -/** - * Form field date/time chooser component. - * - * @constructor - * @param value date/time input value - * @param format date/time format (default YYYY-MM-DD HH:mm) - * @param label label text bound to the input element - * @param rich determines if [label] can contain HTML code - */ -open class DateTime( - value: Date? = null, format: String = "YYYY-MM-DD HH:mm", label: String? = null, - rich: Boolean = false -) : SimplePanel(setOf("form-group")), DateFormControl { - - /** - * Date/time input value. - */ - override var value - get() = input.value - set(value) { - input.value = value - } - /** - * Date/time format. - */ - var format - get() = input.format - set(value) { - input.format = value - } - /** - * The placeholder for the date/time input. - */ - var placeholder - get() = input.placeholder - set(value) { - input.placeholder = value - } - /** - * The name attribute of the generated HTML input element. - */ - var name - get() = input.name - set(value) { - input.name = value - } - override var disabled - get() = input.disabled - set(value) { - input.disabled = value - } - /** - * Determines if the date/time input is automatically focused. - */ - var autofocus - get() = input.autofocus - set(value) { - input.autofocus = value - } - /** - * Determines if the date/time input is read-only. - */ - var readonly - get() = input.readonly - set(value) { - input.readonly = value - } - /** - * Day of the week start. 0 (Sunday) to 6 (Saturday). - */ - var weekStart - get() = input.weekStart - set(value) { - input.weekStart = value - } - /** - * Days of the week that should be disabled. Multiple values should be comma separated. - */ - var daysOfWeekDisabled - get() = input.daysOfWeekDisabled - set(value) { - input.daysOfWeekDisabled = value - } - /** - * Determines if *Clear* button should be visible. - */ - var clearBtn - get() = input.clearBtn - set(value) { - input.clearBtn = value - } - /** - * Determines if *Today* button should be visible. - */ - var todayBtn - get() = input.todayBtn - set(value) { - input.todayBtn = value - } - /** - * Determines if the current day should be highlighted. - */ - var todayHighlight - get() = input.todayHighlight - set(value) { - input.todayHighlight = value - } - /** - * The increment used to build the hour view. - */ - var minuteStep - get() = input.minuteStep - set(value) { - input.minuteStep = value - } - /** - * Determines if meridian views are visible in day and hour views. - */ - var showMeridian - get() = input.showMeridian - set(value) { - input.showMeridian = value - } - /** - * The label text bound to the input element. - */ - var label - get() = flabel.text - set(value) { - flabel.text = value - } - /** - * Determines if [label] can contain HTML code. - */ - var rich - get() = flabel.rich - set(value) { - flabel.rich = value - } - override var size - get() = input.size - set(value) { - input.size = value - } - - private val idc = "kv_form_time_" + counter - final override val input: DateTimeInput = DateTimeInput(value, format).apply { id = idc } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) - final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } - - init { - @Suppress("LeakingThis") - input.eventTarget = this - this.addInternal(flabel) - this.addInternal(input) - this.addInternal(validationInfo) - counter++ - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - if (validatorError != null) { - cl.add("has-error" to true) - } - return cl - } - - @Suppress("UNCHECKED_CAST") - override fun <T : Widget> setEventListener(block: SnOn<T>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun setEventListener(block: SnOn<Widget>.() -> Unit): Widget { - input.setEventListener(block) - return this - } - - override fun removeEventListeners(): Widget { - input.removeEventListeners() - return this - } - - /** - * Open date/time chooser popup. - */ - open fun showPopup() { - input.showPopup() - } - - /** - * Hides date/time chooser popup. - */ - open fun hidePopup() { - input.hidePopup() - } - - override fun getValueAsString(): String? { - return input.getValueAsString() - } - - companion object { - internal var counter = 0 - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.dateTime( - value: Date? = null, format: String = "YYYY-MM-DD HH:mm", label: String? = null, - rich: Boolean = false, init: (DateTime.() -> Unit)? = null - ): DateTime { - val dateTime = DateTime(value, format, label, rich).apply { init?.invoke(this) } - this.add(dateTime) - return dateTime - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt deleted file mode 100644 index 867a3aba..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt +++ /dev/null @@ -1,272 +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.form.time - -import com.github.snabbdom.VNode -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.form.InputSize -import pl.treksoft.kvision.utils.obj -import pl.treksoft.kvision.utils.toDateF -import pl.treksoft.kvision.utils.toStringF -import kotlin.js.Date - -internal const val DEFAULT_MINUTE_STEP = 5 -internal const val MAX_VIEW = 4 - -/** - * Basic date/time chooser component. - * - * @constructor - * @param value date/time input value - * @param format date/time format (default YYYY-MM-DD HH:mm) - * @param classes a set of CSS class names - */ -@Suppress("TooManyFunctions") -open class DateTimeInput( - value: Date? = null, format: String = "YYYY-MM-DD HH:mm", - classes: Set<String> = setOf() -) : Widget(classes + "form-control") { - - init { - this.setInternalEventListener<DateTimeInput> { - change = { - self.changeValue() - } - } - } - - /** - * Date/time input value. - */ - var value by refreshOnUpdate(value, { refreshState() }) - /** - * Date/time format. - */ - var format by refreshOnUpdate(format, { refreshDatePicker() }) - /** - * The placeholder for the date/time input. - */ - var placeholder: String? by refreshOnUpdate() - /** - * The name attribute of the generated HTML input element. - */ - var name: String? by refreshOnUpdate() - /** - * Determines if the field is disabled. - */ - var disabled by refreshOnUpdate(false) - /** - * Determines if the text input is automatically focused. - */ - var autofocus: Boolean? by refreshOnUpdate() - /** - * Determines if the date/time input is read-only. - */ - var readonly: Boolean? by refreshOnUpdate() - /** - * The size of the input. - */ - var size: InputSize? by refreshOnUpdate() - /** - * Day of the week start. 0 (Sunday) to 6 (Saturday). - */ - var weekStart by refreshOnUpdate(0, { refreshDatePicker() }) - /** - * Days of the week that should be disabled. Multiple values should be comma separated. - */ - var daysOfWeekDisabled by refreshOnUpdate(arrayOf<Int>(), { refreshDatePicker() }) - /** - * Determines if *Clear* button should be visible. - */ - var clearBtn by refreshOnUpdate(true, { refreshDatePicker() }) - /** - * Determines if *Today* button should be visible. - */ - var todayBtn by refreshOnUpdate(false, { refreshDatePicker() }) - /** - * Determines if the current day should be highlighted. - */ - var todayHighlight by refreshOnUpdate(false, { refreshDatePicker() }) - /** - * The increment used to build the hour view. - */ - var minuteStep by refreshOnUpdate(DEFAULT_MINUTE_STEP, { refreshDatePicker() }) - /** - * Determines if meridian views are visible in day and hour views. - */ - var showMeridian by refreshOnUpdate(false, { refreshDatePicker() }) - - override fun render(): VNode { - return render("input") - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - size?.let { - cl.add(it.className to true) - } - return cl - } - - override fun getSnAttrs(): List<StringPair> { - val sn = super.getSnAttrs().toMutableList() - sn.add("type" to "text") - placeholder?.let { - sn.add("placeholder" to it) - } - name?.let { - sn.add("name" to it) - } - autofocus?.let { - if (it) { - sn.add("autofocus" to "autofocus") - } - } - readonly?.let { - if (it) { - sn.add("readonly" to "readonly") - } - } - if (disabled) { - sn.add("disabled" to "disabled") - value?.let { - sn.add("value" to it.toStringF(format)) - } - } - return sn - } - - @Suppress("UnsafeCastFromDynamic") - protected open fun refreshState() { - value?.let { - getElementJQueryD()?.datetimepicker("update", it) - } ?: run { - getElementJQueryD()?.`val`(null) - getElementJQueryD()?.datetimepicker("update", null) - } - } - - protected open fun refreshDatePicker() { - getElementJQueryD()?.`val`(null) - getElementJQueryD()?.datetimepicker("remove") - initDateTimePicker() - refreshState() - } - - protected open fun changeValue() { - val v = getElementJQuery()?.`val`() as String? - if (v != null && v.isNotEmpty()) { - this.value = v.toDateF(format) - } else { - this.value = null - } - } - - /** - * Open date/time chooser popup. - */ - open fun showPopup() { - getElementJQueryD()?.datetimepicker("show") - } - - /** - * Hides date/time chooser popup. - */ - open fun hidePopup() { - getElementJQueryD()?.datetimepicker("hide") - } - - @Suppress("UnsafeCastFromDynamic") - override fun afterInsert(node: VNode) { - if (!this.disabled) { - this.initDateTimePicker() - this.getElementJQuery()?.on("changeDate", { e, _ -> - this.dispatchEvent("change", obj { detail = e }) - }) - this.getElementJQuery()?.on("show", { e, _ -> - this.dispatchEvent("showBsDateTime", obj { detail = e }) - }) - this.getElementJQuery()?.on("hide", { e, _ -> - this.dispatchEvent("hideBsDateTime", obj { detail = e }) - }) - refreshState() - } - } - - override fun afterDestroy() { - getElementJQueryD()?.datetimepicker("remove") - } - - private fun initDateTimePicker() { - val datePickerFormat = format.toDatePickerFormat() - val minView = if (format.contains("HH") || format.contains("mm")) 0 else 2 - val maxView = if (format.contains("YY") || format.contains("M") || format.contains("D")) MAX_VIEW else 1 - val startView = if (maxView < 2) maxView else 2 - getElementJQueryD()?.datetimepicker(obj { - this.format = datePickerFormat - this.startView = startView - this.minView = minView - this.maxView = maxView - this.minuteStep = minuteStep - this.todayHighlight = todayHighlight - this.clearBtn = clearBtn - this.todayBtn = todayBtn - this.weekStart = weekStart - this.showMeridian = showMeridian - this.daysOfWeekDisabled = daysOfWeekDisabled - this.autoclose = true - }) - } - - /** - * Get value of date/time input control as String - * @return value as a String - */ - fun getValueAsString(): String? { - return value?.toStringF(format) - } - - companion object { - private fun String.toDatePickerFormat(): String { - return this.replace("YY", "yy").replace("m", "i").replace("MMMM", "{----}").replace("MMM", "{---}") - .replace("M", "m").replace("{----}", "MM").replace("{---}", "M").replace("H", "{-}") - .replace("h", "H").replace("{-}", "h").replace("D", "d").replace("a", "p").replace("A", "P") - } - - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.dateTimeInput( - value: Date? = null, format: String = "YYYY-MM-DD HH:mm", classes: Set<String> = setOf(), - init: (DateTimeInput.() -> Unit)? = null - ): DateTimeInput { - val dateTimeInput = DateTimeInput(value, format, classes).apply { init?.invoke(this) } - this.add(dateTimeInput) - return dateTimeInput - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/hmr/ApplicationBase.kt b/src/main/kotlin/pl/treksoft/kvision/hmr/ApplicationBase.kt deleted file mode 100644 index 3183f71a..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/hmr/ApplicationBase.kt +++ /dev/null @@ -1,41 +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.hmr - -/** - * Base interface for applications. - * - * Base interface for applications supporting Hot Module Replacement (HMR). - */ -interface ApplicationBase { - /** - * Starting point for an application. - * @param state Initial state between Hot Module Replacement (HMR). - */ - fun start(state: Map<String, Any>) - - /** - * Ending point for an application. - * @return final state for Hot Module Replacement (HMR). - */ - fun dispose(): Map<String, Any> -} diff --git a/src/main/kotlin/pl/treksoft/kvision/hmr/HMR.kt b/src/main/kotlin/pl/treksoft/kvision/hmr/HMR.kt deleted file mode 100644 index 62cde4d9..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/hmr/HMR.kt +++ /dev/null @@ -1,47 +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.hmr - -/** - * Helper variable for Hot Module Replacement (HMR). - */ -external val module: Module - -/** - * Helper interface for Hot Module Replacement (HMR). - */ -external interface Module { - val hot: Hot? -} - -/** - * Helper interface for Hot Module Replacement (HMR). - */ -external interface Hot { - val data: dynamic - - fun accept() - fun accept(dependency: String, callback: () -> Unit) - fun accept(dependencies: Array<String>, callback: (updated: Array<String>) -> Unit) - - fun dispose(callback: (data: dynamic) -> Unit) -} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt deleted file mode 100644 index 84f7c309..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt +++ /dev/null @@ -1,150 +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.html - -import com.github.snabbdom.VNode -import org.w3c.dom.events.MouseEvent -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.ResString -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.core.Widget - -/** - * Button styles. - */ -enum class ButtonStyle(internal val className: String) { - DEFAULT("btn-default"), - PRIMARY("btn-primary"), - SUCCESS("btn-success"), - INFO("btn-info"), - WARNING("btn-warning"), - DANGER("btn-danger"), - LINK("btn-link") -} - -/** - * Button sizes. - */ -enum class ButtonSize(internal val className: String) { - LARGE("btn-lg"), - SMALL("btn-sm"), - XSMALL("btn-xs") -} - -/** - * Button component. - * - * @constructor - * @param text button label - * @param icon button icon - * @param style button style - * @param disabled button state - * @param classes a set of CSS class names - */ -open class Button( - text: String, icon: String? = null, style: ButtonStyle = ButtonStyle.DEFAULT, - disabled: Boolean = false, classes: Set<String> = setOf() -) : Widget(classes) { - - /** - * Button label. - */ - var text by refreshOnUpdate(text) - /** - * Button icon. - */ - var icon by refreshOnUpdate(icon) - /** - * Button style. - */ - var style by refreshOnUpdate(style) - /** - * Determines if button is disabled. - */ - var disabled by refreshOnUpdate(disabled) - /** - * Button image. - */ - var image: ResString? by refreshOnUpdate() - /** - * Button size. - */ - var size: ButtonSize? by refreshOnUpdate() - /** - * Determines if the button takes all the space horizontally. - */ - var block by refreshOnUpdate(false) - - override fun render(): VNode { - val t = createLabelWithIcon(text, icon, image) - return render("button", t) - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - cl.add("btn" to true) - cl.add(style.className to true) - size?.let { - cl.add(it.className to true) - } - if (block) { - cl.add("btn-block" to true) - } - if (disabled) { - cl.add("disabled" to true) - } - return cl - } - - override fun getSnAttrs(): List<StringPair> { - return super.getSnAttrs() + ("type" to "button") - } - - /** - * A convenient helper for easy setting onClick event handler. - */ - open fun onClick(handler: Button.(MouseEvent) -> Unit): Button { - this.setEventListener<Button> { - click = { e -> - self.handler(e) - } - } - return this - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.button( - text: String, icon: String? = null, style: ButtonStyle = ButtonStyle.DEFAULT, - disabled: Boolean = false, classes: Set<String> = setOf(), init: (Button.() -> Unit)? = null - ): Button { - val button = Button(text, icon, style, disabled, classes).apply { init?.invoke(this) } - this.add(button) - return button - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Div.kt b/src/main/kotlin/pl/treksoft/kvision/html/Div.kt deleted file mode 100644 index 38dc5817..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/html/Div.kt +++ /dev/null @@ -1,65 +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.html - -import pl.treksoft.kvision.core.Container - -/** - * Simple component rendered as *div*. - * - * @constructor - * @param text element text - * @param rich determines if [text] can contain HTML code - */ -open class Div( - text: String, - rich: Boolean = false, - align: Align? = null, - classes: Set<String> = setOf(), - init: (Div.() -> Unit)? = null -) : - Tag(TAG.DIV, text, rich, align, classes) { - - init { - @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.div( - text: String, - rich: Boolean = false, - align: Align? = null, - classes: Set<String> = setOf(), - init: (Div.() -> Unit)? = null - ): Div { - val div = Div(text, rich, align, classes).apply { init?.invoke(this) } - this.add(div) - return div - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt deleted file mode 100644 index 61733fb3..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt +++ /dev/null @@ -1,118 +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.html - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.ResString -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.core.Widget - -/** - * Image shapes. - */ -enum class ImageShape(internal val className: String) { - ROUNDED("img-rounded"), - CIRCLE("img-circle"), - THUMBNAIL("img-thumbnail") -} - -/** - * Image component. - * - * @constructor - * @param src image URL - * @param alt alternative text - * @param responsive determines if the image is rendered as responsive - * @param shape image shape - * @param centered determines if the image is rendered centered - * @param classes a set of CSS class names - */ -open class Image( - src: ResString, alt: String? = null, responsive: Boolean = false, shape: ImageShape? = null, - centered: Boolean = false, classes: Set<String> = setOf() -) : Widget(classes) { - /** - * URL of the image. - */ - var src by refreshOnUpdate(src) - /** - * The alternative text of the image. - */ - var alt by refreshOnUpdate(alt) - /** - * Determines if the image is rendered as responsive. - */ - var responsive by refreshOnUpdate(responsive) - /** - * The shape of the image. - */ - var shape by refreshOnUpdate(shape) - /** - * Determines if the image is rendered as centered. - */ - var centered by refreshOnUpdate(centered) - - override fun render(): VNode { - return render("img") - } - - override fun getSnAttrs(): List<StringPair> { - val pr = super.getSnAttrs().toMutableList() - pr.add("src" to src) - alt?.let { - pr.add("alt" to it) - } - return pr - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - if (responsive) { - cl.add("img-responsive" to true) - } - if (centered) { - cl.add("center-block" to true) - } - shape?.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.image( - src: ResString, alt: String? = null, responsive: Boolean = false, shape: ImageShape? = null, - centered: Boolean = false, classes: Set<String> = setOf(), init: (Image.() -> Unit)? = null - ): Image { - val image = Image(src, alt, responsive, shape, centered, classes).apply { init?.invoke(this) } - this.add(image) - return image - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Label.kt b/src/main/kotlin/pl/treksoft/kvision/html/Label.kt deleted file mode 100644 index e56362ef..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/html/Label.kt +++ /dev/null @@ -1,48 +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.html - -import pl.treksoft.kvision.core.Container - -/** - * Simple label component rendered as *span*. - * - * @constructor - * @param text label text - * @param rich determines if [text] can contain HTML code - */ -open class Label(text: String, rich: Boolean = false) : Tag(TAG.SPAN, text, rich) { - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.label( - text: String, rich: Boolean = false, init: (Label.() -> Unit)? = null - ): Label { - val label = Label(text, rich).apply { init?.invoke(this) } - this.add(label) - return label - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt deleted file mode 100644 index 94c7c594..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt +++ /dev/null @@ -1,85 +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.html - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.ResString -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.panel.SimplePanel - -/** - * Link component. - * - * @constructor - * @param label link label - * @param url link URL address - * @param icon link icon - * @param image link image - * @param classes a set of CSS class names - */ -open class Link( - label: String, url: String, icon: String? = null, image: ResString? = null, - classes: Set<String> = setOf() -) : SimplePanel(classes) { - /** - * Link label. - */ - var label by refreshOnUpdate(label) - /** - * Link URL address. - */ - var url by refreshOnUpdate(url) - /** - * Link icon. - */ - var icon by refreshOnUpdate(icon) - /** - * Link image. - */ - var image by refreshOnUpdate(image) - - override fun render(): VNode { - val t = createLabelWithIcon(label, icon, image) - return render("a", t + childrenVNodes()) - } - - override fun getSnAttrs(): List<StringPair> { - return super.getSnAttrs() + ("href" to url) - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.link( - label: String, url: String, icon: String? = null, image: ResString? = null, - classes: Set<String> = setOf(), init: (Link.() -> Unit)? = null - ): Link { - val link = Link(label, url, icon, image, classes).apply { init?.invoke(this) } - this.add(link) - return link - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/List.kt b/src/main/kotlin/pl/treksoft/kvision/html/List.kt deleted file mode 100644 index fb49cd62..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/html/List.kt +++ /dev/null @@ -1,150 +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.html - -import com.github.snabbdom.VNode -import com.github.snabbdom.h -import pl.treksoft.kvision.KVManager -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.panel.SimplePanel - -/** - * HTML list types. - */ -enum class ListType(internal val tagName: String) { - UL("ul"), - OL("ol"), - UNSTYLED("ul"), - INLINE("ul"), - DL("dl"), - DL_HORIZ("dl") -} - -/** - * HTML list component. - * - * The list component can be populated directly from *elements* parameter or manually by adding - * any [Component] to the container. - * - * @constructor - * @param type list type - * @param elements optional list of elements - * @param rich determines if [elements] can contain HTML code - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class ListTag( - type: ListType, elements: List<String>? = null, rich: Boolean = false, - classes: Set<String> = setOf(), init: (ListTag.() -> Unit)? = null -) : SimplePanel(classes) { - /** - * List type. - */ - var type by refreshOnUpdate(type) - /** - * List of elements. - */ - var elements by refreshOnUpdate(elements) - /** - * Determines if [elements] can contain HTML code. - */ - var rich by refreshOnUpdate(rich) - - init { - @Suppress("LeakingThis") - init?.invoke(this) - } - - override fun render(): VNode { - val childrenElements = when (type) { - ListType.UL, ListType.OL, ListType.UNSTYLED, ListType.INLINE -> elements?.map { el -> - element("li", el, rich) - } - ListType.DL, ListType.DL_HORIZ -> elements?.mapIndexed { index, el -> - element(if (index % 2 == 0) "dt" else "dd", el, rich) - } - }?.toTypedArray() - return if (childrenElements != null) { - render(type.tagName, childrenElements + childrenVNodes()) - } else { - render(type.tagName, childrenVNodes()) - } - } - - override fun childrenVNodes(): Array<VNode> { - val childrenElements = children.filter { it.visible } - val res = when (type) { - ListType.UL, ListType.OL, ListType.UNSTYLED, ListType.INLINE -> childrenElements.map { v -> - if (v is Tag && v.type == TAG.LI) { - v.renderVNode() - } else { - h("li", arrayOf(v.renderVNode())) - } - } - ListType.DL, ListType.DL_HORIZ -> childrenElements.mapIndexed { index, v -> - if (v is Tag && v.type == TAG.LI) { - v.renderVNode() - } else { - h(if (index % 2 == 0) "dt" else "dd", arrayOf(v.renderVNode())) - } - } - } - return res.toTypedArray() - } - - private fun element(name: String, value: String, rich: Boolean): VNode { - return if (rich) { - h(name, arrayOf(KVManager.virtualize("<span>$value</span>"))) - } else { - h(name, value) - } - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - @Suppress("NON_EXHAUSTIVE_WHEN") - when (type) { - ListType.UNSTYLED -> cl.add("list-unstyled" to true) - ListType.INLINE -> cl.add("list-inline" to true) - ListType.DL_HORIZ -> cl.add("dl-horizontal" to true) - } - return cl - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.listTag( - type: ListType, elements: List<String>? = null, rich: Boolean = false, - classes: Set<String> = setOf(), init: (ListTag.() -> Unit)? = null - ): ListTag { - val listTag = ListTag(type, elements, rich, classes, init) - this.add(listTag) - return listTag - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt deleted file mode 100644 index 33ef2cb7..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt +++ /dev/null @@ -1,155 +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.html - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.KVManager -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.panel.SimplePanel - -/** - * HTML tags. - */ -@Suppress("EnumNaming") -enum class TAG(internal val tagName: String) { - H1("h1"), - H2("h2"), - H3("h3"), - H4("h4"), - H5("h5"), - H6("h6"), - P("p"), - ABBR("abbr"), - ADDRESS("address"), - BLOCKQUOTE("blockquote"), - SECTION("section"), - HEADER("header"), - FOOTER("footer"), - PRE("pre"), - UL("ul"), - OL("ol"), - DIV("div"), - LABEL("label"), - - MARK("mark"), - DEL("del"), - S("s"), - INS("ins"), - U("u"), - SMALL("small"), - STRONG("strong"), - EM("em"), - CITE("cite"), - CODE("code"), - KBD("kbd"), - VAR("var"), - SAMP("samp"), - SPAN("span"), - LI("li") -} - -/** - * CSS align attributes. - */ -enum class Align(val className: String) { - LEFT("text-left"), - CENTER("text-center"), - RIGHT("text-right"), - JUSTIFY("text-justify"), - NOWRAP("text-nowrap") -} - -/** - * HTML tag component. - * - * @constructor - * @param type tag type - * @param text text content of the tag - * @param rich determines if [text] can contain HTML code - * @param align text align - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class Tag( - type: TAG, text: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set<String> = setOf(), init: (Tag.() -> Unit)? = null -) : SimplePanel(classes) { - - /** - * Tag type. - */ - var type by refreshOnUpdate(type) - /** - * Text content of the tag. - */ - var text by refreshOnUpdate(text) - /** - * Determines if [text] can contain HTML code. - */ - var rich by refreshOnUpdate(rich) - /** - * Text align. - */ - var align by refreshOnUpdate(align) - - init { - @Suppress("LeakingThis") - init?.invoke(this) - } - - override fun render(): VNode { - return if (text != null) { - if (rich) { - render(type.tagName, arrayOf(KVManager.virtualize("<span>$text</span>")) + childrenVNodes()) - } else { - render(type.tagName, childrenVNodes() + arrayOf(text)) - } - } else { - render(type.tagName, childrenVNodes()) - } - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - align?.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.tag( - type: TAG, text: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set<String> = setOf(), init: (Tag.() -> Unit)? = null - ): Tag { - val tag = Tag(type, text, rich, align, classes, init) - this.add(tag) - return tag - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt deleted file mode 100644 index de5bcd3b..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt +++ /dev/null @@ -1,121 +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.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() = content.text - set(value) { - content.text = value - } - /** - * Determines if [text] can contain HTML code. - */ - var rich - get() = content.rich - set(value) { - content.rich = value - } - /** - * Text align. - */ - var align - get() = content.align - set(value) { - content.align = value - } - - private val content = Tag(TAG.DIV, text, rich, align) - - init { - body.add(content) - 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/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt b/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt deleted file mode 100644 index 5f0440a6..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/modal/CloseIcon.kt +++ /dev/null @@ -1,48 +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.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'>×</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/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt deleted file mode 100644 index 55310d50..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt +++ /dev/null @@ -1,143 +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.modal - -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 - -/** - * 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 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, - private val noCallback: (() -> Unit)? = null, - private val yesCallback: (() -> Unit)? = null -) : Modal(caption, false, size, animation, false) { - /** - * Window content text. - */ - var text - get() = content.text - set(value) { - content.text = value - } - /** - * Determines if [text] can contain HTML code. - */ - var rich - get() = content.rich - set(value) { - content.rich = value - } - /** - * Text align. - */ - var align - get() = content.align - set(value) { - content.align = value - } - /** - * Determines if Cancel button is visible. - */ - var cancelVisible by refreshOnUpdate(cancelVisible, { refreshCancelButton() }) - - private val content = Tag(TAG.DIV, text, rich, align) - private val cancelButton = Button("Cancel", "remove") - - init { - body.add(content) - cancelButton.setEventListener { - click = { - hide() - } - } - this.addButton(cancelButton) - val noButton = Button("No", "ban-circle") - noButton.setEventListener { - click = { - hide() - noCallback?.invoke() - } - } - this.addButton(noButton) - val yesButton = Button("Yes", "ok", ButtonStyle.PRIMARY) - 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, - noCallback: (() -> Unit)? = null, yesCallback: (() -> Unit)? = null - ) { - Confirm(caption, text, rich, align, size, animation, cancelVisible, noCallback, yesCallback).show() - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt deleted file mode 100644 index 8e434d73..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt +++ /dev/null @@ -1,282 +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.modal - -import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.Component -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.SimplePanel -import pl.treksoft.kvision.utils.obj - -/** - * Modal window sizes. - */ -enum class ModalSize(val className: String) { - 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) { - - /** - * Window caption text. - */ - var caption - get() = captionTag.text - set(value) { - captionTag.text = 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.H4, 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.addInternal(dialog) - val content = SimplePanel(setOf("modal-content")) - dialog.role = "document" - dialog.add(content) - closeIcon.visible = closeButton - closeIcon.setEventListener { - click = { - hide() - } - } - header.add(closeIcon) - header.add(captionTag) - checkHeaderVisibility() - content.add(header) - content.add(body) - content.add(footer) - val root = Root.getLastRoot() - if (root != null) { - @Suppress("LeakingThis") - root.addModal(this) - } else { - println("At least one Root object is required to create a modal!") - } - @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 getSnAttrs(): List<StringPair> { - val pr = super.getSnAttrs().toMutableList() - pr.add("tabindex" to "-1") - return pr - } - - override fun getSnClass(): List<StringBoolPair> { - val cl = super.getSnClass().toMutableList() - cl.add("modal" to true) - 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 - 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") - } -} - -/** - * 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/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt deleted file mode 100644 index 3a5f25f2..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt +++ /dev/null @@ -1,202 +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 - -/** - * Dock layout directions. - */ -enum class Side { - LEFT, - RIGHT, - CENTER, - UP, - DOWN -} - -/** - * The container with dock layout (up, down, left, right and center positions). - * - * @constructor - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class DockPanel(classes: Set<String> = setOf(), init: (DockPanel.() -> Unit)? = null) : - SimplePanel(classes = classes) { - /** - * @suppress - * Internal property. - */ - protected var leftComponent: Component? = null - /** - * @suppress - * Internal property. - */ - protected var centerComponent: Component? = null - /** - * @suppress - * Internal property. - */ - protected var rightComponent: Component? = null - /** - * @suppress - * Internal property. - */ - protected var upComponent: Component? = null - /** - * @suppress - * Internal property. - */ - protected var downComponent: Component? = null - - /** - * @suppress - * Internal property. - */ - protected val mainContainer = FlexPanel( - direction = FlexDir.COLUMN, justify = FlexJustify.SPACEBETWEEN, - alignItems = FlexAlignItems.STRETCH - ) - /** - * @suppress - * Internal property. - */ - protected val subContainer = FlexPanel(justify = FlexJustify.SPACEBETWEEN, alignItems = FlexAlignItems.CENTER) - - init { - this.addInternal(mainContainer) - mainContainer.add(subContainer, 2) - @Suppress("LeakingThis") - init?.invoke(this) - } - - /** - * Adds a component to the dock container. - * @param child child component - * @param position position in the dock - * @return current container - */ - @Suppress("MagicNumber") - open fun add(child: Component, position: Side): DockPanel { - when (position) { - Side.UP -> { - upComponent?.let { mainContainer.remove(it) } - upComponent = child - mainContainer.add(child, 1, alignSelf = FlexAlignItems.CENTER) - } - Side.CENTER -> { - centerComponent?.let { subContainer.remove(it) } - centerComponent = child - subContainer.add(child, 2) - } - Side.LEFT -> { - leftComponent?.let { subContainer.remove(it) } - leftComponent = child - subContainer.add(child, 1) - } - Side.RIGHT -> { - rightComponent?.let { subContainer.remove(it) } - rightComponent = child - subContainer.add(child, 3) - } - Side.DOWN -> { - downComponent?.let { mainContainer.remove(it) } - downComponent = child - mainContainer.add(child, 3, alignSelf = FlexAlignItems.CENTER) - } - } - return this - } - - override fun add(child: Component): DockPanel { - return this.add(child, Side.CENTER) - } - - override fun addAll(children: List<Component>): DockPanel { - children.forEach { this.add(it) } - return this - } - - override fun remove(child: Component): DockPanel { - if (child == leftComponent) removeAt(Side.LEFT) - if (child == centerComponent) removeAt(Side.CENTER) - if (child == rightComponent) removeAt(Side.RIGHT) - if (child == upComponent) removeAt(Side.UP) - if (child == downComponent) removeAt(Side.DOWN) - return this - } - - /** - * Removes child from given position in the dock. - * @param position position in the dock - * @return current container - */ - open fun removeAt(position: Side): DockPanel { - when (position) { - Side.UP -> { - upComponent?.let { mainContainer.remove(it) } - upComponent = null - } - Side.CENTER -> { - centerComponent?.let { subContainer.remove(it) } - centerComponent = null - } - Side.LEFT -> { - leftComponent?.let { subContainer.remove(it) } - leftComponent = null - } - Side.RIGHT -> { - rightComponent?.let { subContainer.remove(it) } - rightComponent = null - } - Side.DOWN -> { - downComponent?.let { mainContainer.remove(it) } - downComponent = null - } - } - return this - } - - override fun removeAll(): DockPanel { - removeAt(Side.LEFT) - removeAt(Side.CENTER) - removeAt(Side.RIGHT) - removeAt(Side.UP) - removeAt(Side.DOWN) - return this - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.dockPanel(classes: Set<String> = setOf(), init: (DockPanel.() -> Unit)? = null): DockPanel { - val dockPanel = DockPanel(classes, init) - this.add(dockPanel) - return dockPanel - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt deleted file mode 100644 index d22a285b..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt +++ /dev/null @@ -1,269 +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.StringPair -import pl.treksoft.kvision.core.StyledComponent -import pl.treksoft.kvision.core.WidgetWrapper -import pl.treksoft.kvision.utils.px - -/** - * CSS flexbox directions. - */ -enum class FlexDir(internal val dir: String) { - ROW("row"), - ROWREV("row-reverse"), - COLUMN("column"), - COLUMNREV("column-reverse") -} - -/** - * CSS flexbox wrap modes. - */ -enum class FlexWrap(internal val wrap: String) { - NOWRAP("nowrap"), - WRAP("wrap"), - WRAPREV("wrap-reverse") -} - -/** - * CSS flexbox justification options. - */ -enum class FlexJustify(internal val justify: String) { - FLEXSTART("flex-start"), - FLEXEND("flex-end"), - CENTER("center"), - SPACEBETWEEN("space-between"), - SPACEAROUND("space-around"), - SPACEEVENLY("space-evenly") -} - -/** - * CSS flexbox alignments options. - */ -enum class FlexAlignItems(internal val alignItems: String) { - FLEXSTART("flex-start"), - FLEXEND("flex-end"), - CENTER("center"), - BASELINE("baseline"), - STRETCH("stretch") -} - -/** - * CSS flexbox content alignment options. - */ -enum class FlexAlignContent(internal val alignContent: String) { - FLEXSTART("flex-start"), - FLEXEND("flex-end"), - CENTER("center"), - SPACEBETWEEN("space-between"), - SPACEAROUND("space-around"), - STRETCH("stretch") -} - -/** - * The container with CSS flexbox layout support. - * - * @constructor - * @param direction flexbox direction - * @param wrap flexbox wrap - * @param justify flexbox content justification - * @param alignItems flexbox items alignment - * @param alignContent flexbox content alignment - * @param spacing spacing between columns/rows - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class FlexPanel( - direction: FlexDir? = null, wrap: FlexWrap? = null, justify: FlexJustify? = null, - alignItems: FlexAlignItems? = null, alignContent: FlexAlignContent? = null, - spacing: Int? = null, classes: Set<String> = setOf(), init: (FlexPanel.() -> Unit)? = null -) : SimplePanel(classes) { - - /** - * CSS flexbox direction. - */ - var direction by refreshOnUpdate(direction, { refreshSpacing(); refresh() }) - /** - * CSS flexbox wrap mode. - */ - var wrap by refreshOnUpdate(wrap) - /** - * CSS flexbox content justification. - */ - var justify by refreshOnUpdate(justify) - /** - * CSS flexbox items alignment. - */ - var alignItems by refreshOnUpdate(alignItems) - /** - * CSS flexbox content alignment. - */ - var alignContent by refreshOnUpdate(alignContent) - /** - * The spacing between columns/rows. - */ - var spacing by refreshOnUpdate(spacing, { refreshSpacing(); refresh() }) - - init { - @Suppress("LeakingThis") - init?.invoke(this) - } - - /** - * Adds a component to the flexbox container. - * @param child child component - * @param order child flexbox ordering - * @param grow child flexbox grow - * @param shrink child flexbox shrink - * @param basis child flexbox basis - * @param alignSelf child self alignment - * @param classes a set of CSS class names - */ - @Suppress("LongParameterList") - fun add( - child: Component, order: Int? = null, grow: Int? = null, shrink: Int? = null, - basis: Int? = null, alignSelf: FlexAlignItems? = null, classes: Set<String> = setOf() - ): FlexPanel { - val wrapper = FlexWrapper(child, order, grow, shrink, basis, alignSelf, classes) - addInternal(applySpacing(wrapper)) - return this - } - - private fun refreshSpacing() { - getChildren().filterIsInstance<StyledComponent>().map { applySpacing(it) } - } - - private fun applySpacing(wrapper: StyledComponent): StyledComponent { - wrapper.marginTop = null - wrapper.marginRight = null - wrapper.marginBottom = null - wrapper.marginLeft = null - spacing?.let { - when (direction) { - FlexDir.COLUMN -> wrapper.marginBottom = it.px - FlexDir.ROWREV -> wrapper.marginLeft = it.px - FlexDir.COLUMNREV -> wrapper.marginTop = it.px - else -> wrapper.marginRight = it.px - } - } - return wrapper - } - - override fun add(child: Component): FlexPanel { - return add(child, null) - } - - override fun addAll(children: List<Component>): FlexPanel { - children.forEach { add(it, null) } - return this - } - - override fun remove(child: Component): FlexPanel { - children.find { (it as FlexWrapper).wrapped == child }?.let { - super.remove(it) - it.dispose() - } - return this - } - - override fun removeAll(): FlexPanel { - children.map { - it.clearParent() - it.dispose() - } - children.clear() - refresh() - return this - } - - override fun getSnStyle(): List<StringPair> { - val snstyle = super.getSnStyle().toMutableList() - snstyle.add("display" to "flex") - direction?.let { - snstyle.add("flex-direction" to it.dir) - } - wrap?.let { - snstyle.add("flex-wrap" to it.wrap) - } - justify?.let { - snstyle.add("justify-content" to it.justify) - } - alignItems?.let { - snstyle.add("align-items" to it.alignItems) - } - alignContent?.let { - snstyle.add("align-content" to it.alignContent) - } - return snstyle - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.flexPanel( - direction: FlexDir? = null, wrap: FlexWrap? = null, justify: FlexJustify? = null, - alignItems: FlexAlignItems? = null, alignContent: FlexAlignContent? = null, - spacing: Int? = null, classes: Set<String> = setOf(), init: (FlexPanel.() -> Unit)? = null - ): FlexPanel { - val flexPanel = FlexPanel(direction, wrap, justify, alignItems, alignContent, spacing, classes, init) - this.add(flexPanel) - return flexPanel - } - } -} - -/** - * Helper class form CSS flexbox layout. - */ -internal class FlexWrapper( - delegate: Component, private val order: Int? = null, private val grow: Int? = null, - private val shrink: Int? = null, private val basis: Int? = null, - private val alignSelf: FlexAlignItems? = null, - classes: Set<String> = setOf() -) : WidgetWrapper(delegate, classes) { - - override fun getSnStyle(): List<StringPair> { - val snstyle = super.getSnStyle().toMutableList() - order?.let { - snstyle.add("order" to "$it") - } - grow?.let { - snstyle.add("flex-grow" to "$it") - } - shrink?.let { - snstyle.add("flex-shrink" to "$it") - } - basis?.let { - snstyle.add("flex-basis" to "$it%") - } - alignSelf?.let { - snstyle.add("align-self" to it.alignItems) - } - return snstyle - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt deleted file mode 100644 index 1f5efbb4..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt +++ /dev/null @@ -1,316 +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.StringPair -import pl.treksoft.kvision.core.WidgetWrapper - -/** - * CSS grid justification options. - */ -enum class GridJustify(internal val justify: String) { - START("start"), - END("end"), - CENTER("center"), - STRETCH("stretch") -} - -/** - * CSS grid alignment options. - */ -enum class GridAlign(internal val align: String) { - START("start"), - END("end"), - CENTER("center"), - STRETCH("stretch") -} - -/** - * CSS grid content justification options. - */ -enum class GridJustifyContent(internal val justifyContent: String) { - START("start"), - END("end"), - CENTER("center"), - STRETCH("stretch"), - SPACEAROUND("space-around"), - SPACEBETWEEN("space-between"), - SPACEEVENLY("space-evenly") -} - -/** - * CSS grid content alignment options. - */ -enum class GridAlignContent(internal val alignContent: String) { - START("start"), - END("end"), - CENTER("center"), - STRETCH("stretch"), - SPACEAROUND("space-around"), - SPACEBETWEEN("space-between"), - SPACEEVENLY("space-evenly") -} - -/** - * CSS grid flow options. - */ -enum class GridFlow(internal val flow: String) { - ROW("row"), - COLUMN("column"), - ROWDENSE("row dense"), - COLUMNDENSE("column dense") -} - -/** - * The container with CSS grid layout support. - * - * @constructor - * @param autoColumns grid auto columns - * @param autoRows grid auto rows - * @param autoFlow grid auto flow - * @param templateColumns grid columns template - * @param templateRows grid rows template - * @param templateAreas grid areas template - * @param columnGap grid column gap - * @param rowGap grid row gap - * @param justifyItems grid items justification - * @param alignItems grid items alignment - * @param justifyContent flexbox content justification - * @param alignContent flexbox content alignment - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class GridPanel( - autoColumns: String? = null, autoRows: String? = null, autoFlow: GridFlow? = null, - templateColumns: String? = null, templateRows: String? = null, templateAreas: List<String>? = null, - columnGap: Int? = null, rowGap: Int? = null, justifyItems: GridJustify? = null, - alignItems: GridAlign? = null, justifyContent: GridJustifyContent? = null, - alignContent: GridAlignContent? = null, classes: Set<String> = setOf(), init: (GridPanel.() -> Unit)? = null -) : SimplePanel(classes) { - - /** - * CSS grid auto columns. - */ - var autoColumns by refreshOnUpdate(autoColumns) - /** - * CSS grid auto rows. - */ - var autoRows by refreshOnUpdate(autoRows) - /** - * CSS grid auto flow. - */ - var autoFlow by refreshOnUpdate(autoFlow) - /** - * CSS grid columns template. - */ - var templateColumns by refreshOnUpdate(templateColumns) - /** - * CSS grid rows template. - */ - var templateRows by refreshOnUpdate(templateRows) - /** - * CSS grid areas template. - */ - var templateAreas by refreshOnUpdate(templateAreas) - /** - * CSS grid column gap. - */ - var columnGap by refreshOnUpdate(columnGap) - /** - * CSS grid row gap. - */ - var rowGap by refreshOnUpdate(rowGap) - /** - * CSS grid items justification. - */ - var justifyItems by refreshOnUpdate(justifyItems) - /** - * CSS grid items alignment. - */ - var alignItems by refreshOnUpdate(alignItems) - /** - * CSS grid content justification. - */ - var justifyContent by refreshOnUpdate(justifyContent) - /** - * CSS grid content alignment. - */ - var alignContent by refreshOnUpdate(alignContent) - - init { - @Suppress("LeakingThis") - init?.invoke(this) - } - - /** - * Adds a component to the grid container. - * @param child child component - * @param columnStart number of starting column - * @param rowStart number of starting row - * @param columnEnd number of ending column - * @param rowEnd number of ending row - * @param area grid area - * @param justifySelf child self justification - * @param alignSelf child self alignment - * @param classes a set of CSS class names - * @return current container - */ - @Suppress("LongParameterList") - fun add( - child: Component, columnStart: Int? = null, rowStart: Int? = null, - columnEnd: String? = null, rowEnd: String? = null, area: String? = null, justifySelf: GridJustify? = null, - alignSelf: GridAlign? = null, classes: Set<String> = setOf() - ): GridPanel { - addInternal(GridWrapper(child, columnStart, rowStart, columnEnd, rowEnd, area, justifySelf, alignSelf, classes)) - return this - } - - override fun add(child: Component): GridPanel { - return add(child, null, null) - } - - override fun addAll(children: List<Component>): GridPanel { - children.forEach { add(it, null, null) } - return this - } - - override fun remove(child: Component): GridPanel { - children.find { (it as GridWrapper).wrapped == child }?.let { - super.remove(it) - it.dispose() - } - return this - } - - override fun removeAll(): GridPanel { - children.map { - it.clearParent() - it.dispose() - } - children.clear() - refresh() - return this - } - - @Suppress("ComplexMethod") - override fun getSnStyle(): List<StringPair> { - val snstyle = super.getSnStyle().toMutableList() - snstyle.add("display" to "grid") - autoColumns?.let { - snstyle.add("grid-auto-columns" to it) - } - autoRows?.let { - snstyle.add("grid-auto-rows" to it) - } - autoFlow?.let { - snstyle.add("grid-auto-flow" to it.flow) - } - templateColumns?.let { - snstyle.add("grid-template-columns" to it) - } - templateRows?.let { - snstyle.add("grid-template-rows" to it) - } - templateAreas?.let { - snstyle.add("grid-template-areas" to it.joinToString("\n")) - } - columnGap?.let { - snstyle.add("grid-column-gap" to "${it}px") - } - rowGap?.let { - snstyle.add("grid-row-gap" to "${it}px") - } - justifyItems?.let { - snstyle.add("justify-items" to it.justify) - } - alignItems?.let { - snstyle.add("align-items" to it.align) - } - justifyContent?.let { - snstyle.add("justify-content" to it.justifyContent) - } - alignContent?.let { - snstyle.add("align-content" to it.alignContent) - } - return snstyle - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.gridPanel( - autoColumns: String? = null, autoRows: String? = null, autoFlow: GridFlow? = null, - templateColumns: String? = null, templateRows: String? = null, templateAreas: List<String>? = null, - columnGap: Int? = null, rowGap: Int? = null, justifyItems: GridJustify? = null, - alignItems: GridAlign? = null, justifyContent: GridJustifyContent? = null, - alignContent: GridAlignContent? = null, classes: Set<String> = setOf(), init: (GridPanel.() -> Unit)? = null - ): GridPanel { - val gridPanel = GridPanel( - autoColumns, autoRows, autoFlow, templateColumns, templateRows, templateAreas, - columnGap, rowGap, justifyItems, alignItems, justifyContent, alignContent, classes, init - ) - this.add(gridPanel) - return gridPanel - } - } -} - -class GridWrapper( - delegate: Component, private val columnStart: Int? = null, private val rowStart: Int? = null, - private val columnEnd: String? = null, private val rowEnd: String? = null, - private val area: String? = null, private val justifySelf: GridJustify? = null, - private val alignSelf: GridAlign? = null, - classes: Set<String> = setOf() -) : WidgetWrapper(delegate, classes) { - - override fun getSnStyle(): List<StringPair> { - val snstyle = super.getSnStyle().toMutableList() - columnStart?.let { - snstyle.add("grid-column-start" to "$it") - } - rowStart?.let { - snstyle.add("grid-row-start" to "$it") - } - columnEnd?.let { - snstyle.add("grid-column-end" to it) - } - rowEnd?.let { - snstyle.add("grid-row-end" to it) - } - area?.let { - snstyle.add("grid-area" to it) - } - justifySelf?.let { - snstyle.add("justify-self" to it.justify) - } - alignSelf?.let { - snstyle.add("align-self" to it.align) - } - return snstyle - } - -} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt deleted file mode 100644 index 0700e88a..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt +++ /dev/null @@ -1,70 +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.Container - -/** - * The container with horizontal layout. - * - * This is a special case of the flexbox layout. - * - * @constructor - * @param wrap flexbox wrap - * @param justify flexbox content justification - * @param alignItems flexbox items alignment - * @param spacing spacing between columns/rows - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class HPanel( - wrap: FlexWrap? = null, justify: FlexJustify? = null, alignItems: FlexAlignItems? = null, spacing: Int? = null, - classes: Set<String> = setOf(), init: (HPanel.() -> Unit)? = null -) : FlexPanel( - null, - wrap, justify, alignItems, null, spacing, classes -) { - init { - @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.hPanel( - wrap: FlexWrap? = null, - justify: FlexJustify? = null, - alignItems: FlexAlignItems? = null, - spacing: Int? = null, - classes: Set<String> = setOf(), - init: (HPanel.() -> Unit)? = null - ): HPanel { - val hpanel = HPanel(wrap, justify, alignItems, spacing, classes, init) - this.add(hpanel) - return hpanel - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt deleted file mode 100644 index 4bbca9dd..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt +++ /dev/null @@ -1,185 +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.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) { - XS("xs"), - SM("sm"), - MD("md"), - LG("lg") -} - -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) { - - /** - * 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, 0) - val cCol = maxOf(col, 0) - if (row > rows - 1) rows = cRow + 1 - if (col > cols - 1) cols = cCol + 1 - 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 0 until rows) { - val rowContainer = SimplePanel(setOf("row")) - val row = map[i] - if (row != null) { - (0 until 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("col-" + gridSize.size + "-offset-" + 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/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt deleted file mode 100644 index d81b103d..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt +++ /dev/null @@ -1,96 +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 com.github.snabbdom.VNode -import pl.treksoft.kvision.KVManager -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.modal.Modal - -/** - * Root container. - * - * This container is bound to the specific element in the main HTML file of the project. - * It is always the root of components tree and it is responsible for rendering and updating - * Snabbdom virtual DOM. - * - * @constructor - * @param id ID attribute of element in the main HTML file - * @param fixed if false, the container is rendered with Bootstrap "container-fluid" class, - * otherwise it's rendered with "container" class (default is false) - * @param init an initializer extension function - */ -class Root(id: String, private val fixed: Boolean = false, init: (Root.() -> Unit)? = null) : SimplePanel() { - private val modals: MutableList<Modal> = mutableListOf() - private var rootVnode: VNode = renderVNode() - - internal var renderDisabled = false - - init { - rootVnode = KVManager.patch(id, this.renderVNode()) - this.id = id - roots.add(this) - @Suppress("LeakingThis") - init?.invoke(this) - } - - override fun render(): VNode { - return render("div#" + id, childrenVNodes() + modalsVNodes()) - } - - internal fun addModal(modal: Modal) { - modals.add(modal) - modal.parent = this - refresh() - } - - private fun modalsVNodes(): Array<VNode> { - return modals.filter { it.visible }.map { it.renderVNode() }.toTypedArray() - } - - override fun getSnClass(): List<StringBoolPair> { - val css = if (!fixed) "container-fluid" else "container" - return super.getSnClass() + (css to true) - } - - internal fun reRender(): Root { - if (!renderDisabled) { - rootVnode = KVManager.patch(rootVnode, renderVNode()) - } - return this - } - - override fun getRoot(): Root? { - return this - } - - companion object { - private val roots: MutableList<Root> = mutableListOf() - - internal fun getLastRoot(): Root? { - return if (roots.size > 0) - roots[roots.size - 1] - else - null - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt deleted file mode 100644 index 916cbba3..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt +++ /dev/null @@ -1,116 +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 com.github.snabbdom.VNode -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.Widget - -/** - * Basic container class, rendered as a DIV element with all children directly within. - * - * @constructor - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class SimplePanel(classes: Set<String> = setOf(), init: (SimplePanel.() -> Unit)? = null) : Widget(classes), - Container { - internal val children: MutableList<Component> = mutableListOf() - - init { - @Suppress("LeakingThis") - init?.invoke(this) - } - - override fun render(): VNode { - return render("div", childrenVNodes()) - } - - /** - * Returns the array of the children Snabbdom vnodes. - * @return array of children vnodes - */ - protected open fun childrenVNodes(): Array<VNode> { - return children.filter { it.visible }.map { it.renderVNode() }.toTypedArray() - } - - /** - * Protected and final method to add given component to the current container. - * @param child child component - * @return current container - */ - protected fun addInternal(child: Component): SimplePanel { - children.add(child) - child.parent = this - refresh() - return this - } - - override fun add(child: Component): SimplePanel { - return addInternal(child) - } - - override fun addAll(children: List<Component>): SimplePanel { - this.children.addAll(children) - children.map { it.parent = this } - refresh() - return this - } - - override fun remove(child: Component): SimplePanel { - if (children.remove(child)) { - child.clearParent() - refresh() - } - return this - } - - override fun removeAll(): SimplePanel { - children.map { it.clearParent() } - children.clear() - refresh() - return this - } - - override fun getChildren(): List<Component> { - return ArrayList(children) - } - - override fun dispose() { - 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.simplePanel(classes: Set<String> = setOf(), init: (SimplePanel.() -> Unit)? = null): SimplePanel { - val simplePanel = SimplePanel(classes, init) - this.add(simplePanel) - return simplePanel - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/SplitPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/SplitPanel.kt deleted file mode 100644 index 3c7acbe5..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/SplitPanel.kt +++ /dev/null @@ -1,137 +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 com.github.snabbdom.VNode -import pl.treksoft.jquery.JQuery -import pl.treksoft.jquery.JQueryEventObject -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.StyledComponent -import pl.treksoft.kvision.core.UNIT -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag -import pl.treksoft.kvision.utils.obj - -/** - * Split panel direction. - */ -enum class Direction(internal val dir: String) { - HORIZONTAL("horizontal"), - VERTICAL("vertical") -} - -/** - * The container with draggable splitter. - * - * It is required to have exactly two children, for both sides of the splitter. Otherwise it will be - * rendered as empty. - * - * @constructor - * @param direction direction of the splitter - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class SplitPanel( - private val direction: Direction = Direction.VERTICAL, - classes: Set<String> = setOf(), init: (SplitPanel.() -> kotlin.Unit)? = null -) : SimplePanel(classes + ("splitpanel-" + direction.dir)) { - - @Suppress("LeakingThis") - internal val splitter = Splitter(this, direction) - - init { - @Suppress("LeakingThis") - init?.invoke(this) - } - - @Suppress("UnsafeCastFromDynamic") - internal fun afterInsertSplitter() { - if (children.size == 2) { - val horizontal = direction == Direction.HORIZONTAL - val px = UNIT.px - val self = this - children[0].getElementJQueryD().resizable(obj { - handleSelector = "#" + splitter.id - resizeWidth = !horizontal - resizeHeight = horizontal - onDrag = lok@ { e: JQueryEventObject, _: JQuery, newWidth: Int, newHeight: Int, _: dynamic -> - e.asDynamic()["newWidth"] = newWidth - e.asDynamic()["newHeight"] = newHeight - self.dispatchEvent("dragSplitPanel", obj { detail = e }) - return@lok !e.isDefaultPrevented() - } - onDragEnd = { e: JQueryEventObject, el: JQuery, _: dynamic -> - if (horizontal) { - (children[0] as? StyledComponent)?.height = el.height().toInt() to px - } else { - (children[0] as? StyledComponent)?.width = el.width().toInt() to px - } - self.dispatchEvent("dragEndSplitPanel", obj { detail = e }) - } - }) - } - } - - override fun childrenVNodes(): Array<VNode> { - return if (children.size == 2) { - arrayOf(children[0].renderVNode(), splitter.renderVNode(), children[1].renderVNode()) - } else { - arrayOf() - } - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.splitPanel( - direction: Direction = Direction.VERTICAL, - classes: Set<String> = setOf(), init: (SplitPanel.() -> kotlin.Unit)? = null - ): SplitPanel { - val splitPanel = SplitPanel(direction, classes, init) - this.add(splitPanel) - return splitPanel - } - } -} - -internal class Splitter(private val splitPanel: SplitPanel, direction: Direction) : Tag( - TAG.DIV, - classes = setOf("splitter-" + direction.dir) -) { - private val idc = "kv_splitter_" + counter - - init { - counter++ - this.id = idc - } - - override fun afterInsert(node: VNode) { - splitPanel.afterInsertSplitter() - } - - companion object { - internal var counter = 0 - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt deleted file mode 100644 index da41db9f..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt +++ /dev/null @@ -1,115 +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 com.github.snabbdom.VNode -import pl.treksoft.kvision.core.Component -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.routing.routing - -/** - * The container with only one active (visible) child at any moment. - * - * It supports activating children by a JavaScript route. - * - * @constructor - * @param activateLast determines if added component is automatically activated (default true) - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class StackPanel( - private val activateLast: Boolean = true, - classes: Set<String> = setOf(), init: (StackPanel.() -> Unit)? = null -) : SimplePanel(classes) { - - /** - * The index of active (visible) child. - */ - var activeIndex by refreshOnUpdate(-1) - - init { - @Suppress("LeakingThis") - init?.invoke(this) - } - - override fun childrenVNodes(): Array<VNode> { - return if (activeIndex in children.indices) { - arrayOf(children[activeIndex].renderVNode()) - } else { - arrayOf() - } - } - - /** - * Adds given component and bounds it's activation to a given route. - * @param panel child component - * @param route JavaScript route to activate given child - * @return current container - */ - open fun add(panel: Component, route: String): StackPanel { - add(panel) - val currentIndex = children.size - 1 - routing.on(route, { _ -> activeIndex = currentIndex }).resolve() - return this - } - - override fun add(child: Component): StackPanel { - super.add(child) - if (activateLast) activeIndex = children.size - 1 - else if (activeIndex == -1) activeIndex = 0 - return this - } - - override fun addAll(children: List<Component>): StackPanel { - super.addAll(children) - if (activateLast) activeIndex = this.children.size - 1 - else if (activeIndex == -1) activeIndex = 0 - return this - } - - override fun remove(child: Component): StackPanel { - super.remove(child) - if (activeIndex > children.size - 1) activeIndex = children.size - 1 - return this - } - - override fun removeAll(): StackPanel { - super.removeAll() - if (activeIndex > children.size - 1) activeIndex = children.size - 1 - return this - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.stackPanel( - activateLast: Boolean = true, classes: Set<String> = setOf(), init: (StackPanel.() -> Unit)? = null - ): StackPanel { - val stackPanel = StackPanel(activateLast, classes, init) - this.add(stackPanel) - return stackPanel - } - } -} 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 1ac69b7b..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt +++ /dev/null @@ -1,152 +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.html.Link -import pl.treksoft.kvision.html.TAG -import pl.treksoft.kvision.html.Tag -import pl.treksoft.kvision.routing.routing - -/** - * The container rendering it's children as tabs. - * - * It supports activating children by a JavaScript route. - * - * @constructor - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class TabPanel(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 var nav = Tag(TAG.UL, classes = setOf("nav", "nav-tabs")) - private var content = StackPanel(false) - - init { - this.addInternal(nav) - this.addInternal(content) - - @Suppress("LeakingThis") - init?.invoke(this) - } - - /** - * 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 route JavaScript route to activate given child - * @return current container - */ - open fun addTab( - title: String, panel: Component, icon: String? = null, - image: ResString? = null, route: String? = null - ): TabPanel { - val tag = Tag(TAG.LI) - tag.role = "presentation" - tag.add(Link(title, "#", icon, image)) - val index = nav.children.size - tag.setEventListener { - click = { e -> - activeIndex = index - 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 = index }).resolve() - } - return this - } - - /** - * Removes tab at given index. - */ - open fun removeTab(index: Int): TabPanel { - nav.remove(nav.children[index]) - 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) - } - - override fun removeAll(): TabPanel { - content.removeAll() - nav.removeAll() - refresh() - return this - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun Container.tabPanel(classes: Set<String> = setOf(), init: (TabPanel.() -> Unit)? = null): TabPanel { - val tabPanel = TabPanel(classes, init) - this.add(tabPanel) - return tabPanel - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt deleted file mode 100644 index eb9c138e..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt +++ /dev/null @@ -1,65 +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.Container - -/** - * The container with vertical layout. - * - * This is a special case of the flexbox layout. - * - * @constructor - * @param justify flexbox content justification - * @param alignItems flexbox items alignment - * @param spacing spacing between columns/rows - * @param classes a set of CSS class names - * @param init an initializer extension function - */ -open class VPanel( - justify: FlexJustify? = null, alignItems: FlexAlignItems? = null, spacing: Int? = null, - classes: Set<String> = setOf(), init: (VPanel.() -> Unit)? = null -) : FlexPanel( - FlexDir.COLUMN, - null, justify, alignItems, null, spacing, classes -) { - init { - @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.vPanel( - justify: FlexJustify? = null, alignItems: FlexAlignItems? = null, spacing: Int? = null, - classes: Set<String> = setOf(), init: (VPanel.() -> Unit)? = null - ): VPanel { - val vpanel = VPanel(justify, alignItems, spacing, classes, init) - this.add(vpanel) - return vpanel - } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/routing/Routing.kt b/src/main/kotlin/pl/treksoft/kvision/routing/Routing.kt deleted file mode 100644 index 950dfe1c..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/routing/Routing.kt +++ /dev/null @@ -1,51 +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.routing - -import pl.treksoft.navigo.Navigo - -/** - * A helper class for Navigo JavaScript router. - */ -open class Routing : Navigo(null, true, "#!") { - - companion object { - /** - * Init default routing. - */ - fun start() { - routing = Routing() - } - - /** - * Shutdown default routing. - */ - fun shutdown() { - routing.destroy() - } - } -} - -/** - * Default JavaScript router. - */ -var routing = Routing() diff --git a/src/main/kotlin/pl/treksoft/kvision/utils/Keys.kt b/src/main/kotlin/pl/treksoft/kvision/utils/Keys.kt deleted file mode 100644 index d7e2927a..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/utils/Keys.kt +++ /dev/null @@ -1,31 +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.utils - -/** - * Keycode of the ENTER key. - */ -const val ENTER_KEY = 13 -/** - * Keycode of the ESC key. - */ -const val ESC_KEY = 27 diff --git a/src/main/kotlin/pl/treksoft/kvision/utils/Snabbdom.kt b/src/main/kotlin/pl/treksoft/kvision/utils/Snabbdom.kt deleted file mode 100644 index e719d133..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/utils/Snabbdom.kt +++ /dev/null @@ -1,163 +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.utils - -import com.github.snabbdom.Attrs -import com.github.snabbdom.Classes -import com.github.snabbdom.Hooks -import com.github.snabbdom.On -import com.github.snabbdom.Props -import com.github.snabbdom.VNodeData -import com.github.snabbdom.VNodeStyle -import org.w3c.dom.CustomEvent -import org.w3c.dom.CustomEventInit -import pl.treksoft.jquery.JQueryEventObject -import pl.treksoft.kvision.core.StringBoolPair -import pl.treksoft.kvision.core.StringPair -import pl.treksoft.kvision.core.Widget - -/** - * JavaScript Object type - */ -external class Object - -/** - * Helper function for creating JavaScript objects. - */ -fun obj(init: dynamic.() -> Unit): dynamic { - return (Object()).apply(init) -} - -@Suppress("UnsafeCastFromDynamic") -private fun vNodeData(): VNodeData = js("({})") - -/** - * @suppress - * Internal interface. - */ -interface KvJQueryEventObject : JQueryEventObject { - val clickedIndex: Int -} - -/** - * Helper class for defining custom events. - */ -@Suppress("UnsafeCastFromDynamic") -class KvEvent(type: String, eventInitDict: CustomEventInit) : CustomEvent(type, eventInitDict) { - override val detail: KvJQueryEventObject = obj {} -} - -/** - * @suppress - * Internal interface. - */ -interface BtOn : On { - var showBsDropdown: ((KvEvent) -> kotlin.Unit)? - var shownBsDropdown: ((KvEvent) -> kotlin.Unit)? - var hideBsDropdown: ((KvEvent) -> kotlin.Unit)? - var hiddenBsDropdown: ((KvEvent) -> kotlin.Unit)? - var showBsModal: ((KvEvent) -> kotlin.Unit)? - var shownBsModal: ((KvEvent) -> kotlin.Unit)? - var hideBsModal: ((KvEvent) -> kotlin.Unit)? - var hiddenBsModal: ((KvEvent) -> kotlin.Unit)? - var dragSplitPanel: ((KvEvent) -> kotlin.Unit)? - var dragEndSplitPanel: ((KvEvent) -> kotlin.Unit)? - var showBsSelect: ((KvEvent) -> kotlin.Unit)? - var shownBsSelect: ((KvEvent) -> kotlin.Unit)? - var hideBsSelect: ((KvEvent) -> kotlin.Unit)? - var hiddenBsSelect: ((KvEvent) -> kotlin.Unit)? - var loadedBsSelect: ((KvEvent) -> kotlin.Unit)? - var renderedBsSelect: ((KvEvent) -> kotlin.Unit)? - var refreshedBsSelect: ((KvEvent) -> kotlin.Unit)? - var changedBsSelect: ((KvEvent) -> kotlin.Unit)? - var changeDate: ((KvEvent) -> kotlin.Unit)? - var showBsDateTime: ((KvEvent) -> kotlin.Unit)? - var hideBsDateTime: ((KvEvent) -> kotlin.Unit)? - var onMinBsSpinner: ((KvEvent) -> kotlin.Unit)? - var onMaxBsSpinner: ((KvEvent) -> kotlin.Unit)? - var updateModel: ((KvEvent) -> kotlin.Unit)? -} - -/** - * @suppress - * Internal interface. - */ -interface SnOn<T> : BtOn { - var self: T -} - -/** - * Helper function for creating object parameters for Snabbdom. - */ -fun snOpt(block: VNodeData.() -> Unit) = (vNodeData()::apply)(block) - -@Suppress("UnsafeCastFromDynamic") -internal fun on(widget: Widget): SnOn<Widget> { - val obj = js("({})") - obj["self"] = widget - return obj -} - -@Suppress("UnsafeCastFromDynamic") -internal fun hooks(): Hooks { - return js("({})") -} - -/** - * Helper function for creating style parameters for Snabbdom. - */ -@Suppress("UnsafeCastFromDynamic") -fun snStyle(pairs: List<StringPair>): VNodeStyle { - return obj { - pairs.forEach { (key, value) -> this[key] = value } - } -} - -/** - * Helper function for creating properties parameters for Snabbdom. - */ -@Suppress("UnsafeCastFromDynamic") -fun snProps(pairs: List<StringPair>): Props { - return obj { - pairs.forEach { (key, value) -> this[key] = value } - } -} - -/** - * Helper function for creating classes parameters for Snabbdom. - */ -@Suppress("UnsafeCastFromDynamic") -fun snClasses(pairs: List<StringBoolPair>): Classes { - return obj { - pairs.forEach { (key, value) -> this[key] = value } - } -} - -/** - * Helper function for creating attributes parameters for Snabbdom. - */ -@Suppress("UnsafeCastFromDynamic") -fun snAttrs(pairs: List<StringPair>): Attrs { - return obj { - pairs.forEach { (key, value) -> this[key] = value } - } -} diff --git a/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt b/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt deleted file mode 100644 index a25d8e06..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt +++ /dev/null @@ -1,201 +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. - */ -@file:Suppress("TooManyFunctions") - -package pl.treksoft.kvision.utils - -import pl.treksoft.kvision.KVManager -import pl.treksoft.kvision.core.CssSize -import pl.treksoft.kvision.core.UNIT -import kotlin.browser.window -import kotlin.js.Date - -/** - * Extension property to convert Int to CSS px units. - */ -val Int.px: CssSize - get() { - return Pair(this, UNIT.px) - } - -/** - * Extension property to convert Int to CSS em units. - */ -val Int.em: CssSize - get() { - return Pair(this, UNIT.em) - } - -/** - * Extension property to convert Int to CSS pt units. - */ -val Int.pt: CssSize - get() { - return Pair(this, UNIT.pt) - } - -/** - * Extension property to convert Int to CSS percent units. - */ -val Int.perc: CssSize - get() { - return Pair(this, UNIT.perc) - } - -/** - * Extension property to convert Int to CSS rem units. - */ -val Int.rem: CssSize - get() { - return Pair(this, UNIT.rem) - } - -/** - * Extension property to convert Int to CSS ch units. - */ -val Int.ch: CssSize - get() { - return Pair(this, UNIT.ch) - } - -/** - * Extension property to convert Int to CSS cm units. - */ -val Int.cm: CssSize - get() { - return Pair(this, UNIT.cm) - } - -/** - * Extension property to convert Int to CSS mm units. - */ -val Int.mm: CssSize - get() { - return Pair(this, UNIT.mm) - } - -/** - * Extension property to convert Int to CSS in units. - */ -@Suppress("FunctionNaming") -val Int.`in`: CssSize - get() { - return Pair(this, UNIT.`in`) - } - -/** - * Extension property to convert Int to CSS pc units. - */ -val Int.pc: CssSize - get() { - return Pair(this, UNIT.pc) - } - -/** - * Extension property to convert Int to CSS vh units. - */ -val Int.vh: CssSize - get() { - return Pair(this, UNIT.vh) - } - -/** - * Extension property to convert Int to CSS vw units. - */ -val Int.vw: CssSize - get() { - return Pair(this, UNIT.vw) - } - -/** - * Extension property to convert Int to CSS vmin units. - */ -val Int.vmin: CssSize - get() { - return Pair(this, UNIT.vmin) - } - -/** - * Extension property to convert Int to CSS vmax units. - */ -val Int.vmax: CssSize - get() { - return Pair(this, UNIT.vmax) - } - -/** - * Helper property to describe CSS auto value. - */ -val auto: CssSize = Pair(0, UNIT.auto) - -/** - * Extension function to convert CssSize to String. - */ -fun CssSize.asString(): String { - return if (this.second != UNIT.auto) { - this.first.toString() + this.second.unit - } else { - "auto" - } -} - -private val hex = arrayOf("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f") - -/** - * Extension function to convert Int to hex format. - */ -@Suppress("MagicNumber") -fun Int.toHexString(): String { - var result = "" - var num = this - for (i in 0 until 6) { - result = hex[num and 0xF] + result - num = num shr 4 - } - return result -} - -/** - * Extension function to convert String to Date with a given date format. - * @param format date/time format - * @return Date object - */ -@Suppress("UnsafeCastFromDynamic") -fun String.toDateF(format: String = "YYYY-MM-DD HH:mm:ss"): Date { - return KVManager.fecha.parse(this, format) -} - -/** - * Extension function to convert Date to String with a given date format. - * @param format date/time format - * @return String object - */ -@Suppress("UnsafeCastFromDynamic") -fun Date.toStringF(format: String = "YYYY-MM-DD HH:mm:ss"): String { - return KVManager.fecha.format(this, format) -} - -/** - * Utility function to detect Internet Explorer 11. - * @return true if the current browser is IE11 - */ -fun isIE11(): Boolean = window.navigator.userAgent.matches("Trident\\/7\\.") diff --git a/src/main/kotlin/pl/treksoft/kvision/window/Window.kt b/src/main/kotlin/pl/treksoft/kvision/window/Window.kt deleted file mode 100644 index 79c31e8d..00000000 --- a/src/main/kotlin/pl/treksoft/kvision/window/Window.kt +++ /dev/null @@ -1,312 +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.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.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.TAG -import pl.treksoft.kvision.html.Tag -import pl.treksoft.kvision.modal.CloseIcon -import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.utils.px - -internal const val DEFAULT_Z_INDEX = 1000 -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 classes a set of CSS class names - * @param init an initializer extension function - */ -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, - classes: Set<String> = setOf(), - init: (Window.() -> Unit)? = null -) : - SimplePanel(classes + setOf("modal-content", "kv-window")) { - - /** - * Window caption text. - */ - var caption - get() = captionTag.text - set(value) { - captionTag.text = 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 - } - /** - * 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() - } - - 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 captionTag = Tag(TAG.H4, caption, classes = setOf("modal-title")) - - private var isResizeEvent = false - - init { - id = "kv_window_" + counter - position = Position.ABSOLUTE - overflow = Overflow.HIDDEN - @Suppress("LeakingThis") - width = contentWidth - zIndex = ++zIndexCounter - closeIcon.visible = closeButton - closeIcon.setEventListener { - click = { - hide() - } - } - header.add(closeIcon) - header.add(captionTag) - checkHeaderVisibility() - addInternal(header) - addInternal(content) - checkIsDraggable() - if (isResizable) { - 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() { - if (!closeButton && 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) + 2 - this.height = (intHeight + WINDOW_CONTENT_MARGIN_BOTTOM - 1).px - content.marginBottom = WINDOW_CONTENT_MARGIN_BOTTOM.px - } else { - resize = Resize.NONE - val intHeight = (getElementJQuery()?.height()?.toInt() ?: 0) + 2 - this.height = (intHeight - WINDOW_CONTENT_MARGIN_BOTTOM - 1).px - content.marginBottom = 0.px - } - } - - private fun checkResizablEventHandler() { - if (isResizable) { - isResizeEvent = true - KVManager.setResizeEvent(this) { - val eid = getElementJQuery()?.attr("id") - if (eid == id) { - val intWidth = (getElementJQuery()?.width()?.toInt() ?: 0) + 2 - val intHeight = (getElementJQuery()?.height()?.toInt() ?: 0) + 2 - width = intWidth.px - height = intHeight.px - content.width = (intWidth - 2).px - content.height = (intHeight - WINDOW_HEADER_HEIGHT - WINDOW_CONTENT_MARGIN_BOTTOM - 1 - 2).px - } - } - } else if (isResizeEvent) { - KVManager.clearResizeEvent(this) - } - } - - 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) { - KVManager.clearResizeEvent(this) - } - } - - /** - * 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() - } - - 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, - classes: Set<String> = setOf(), - init: (Window.() -> Unit)? = null - ): Window { - val window = - Window(caption, contentWidth, contentHeight, isResizable, isDraggable, closeButton, classes, init) - this.add(window) - return window - } - } -} diff --git a/src/main/resources/css/style.css b/src/main/resources/css/style.css deleted file mode 100644 index 851cbc53..00000000 --- a/src/main/resources/css/style.css +++ /dev/null @@ -1,133 +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 { - 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 .modal-title { - white-space: nowrap; -} diff --git a/src/main/resources/img/placeholder.png b/src/main/resources/img/placeholder.png deleted file mode 100644 index e69de29b..00000000 --- a/src/main/resources/img/placeholder.png +++ /dev/null diff --git a/src/main/resources/js/bootstrap-select-i18n.min.js b/src/main/resources/js/bootstrap-select-i18n.min.js deleted file mode 100644 index 4428d3c0..00000000 --- a/src/main/resources/js/bootstrap-select-i18n.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof module&&module.exports?module.exports=b(require("jquery")):b(a.jQuery)}(this,function(a){!function(a){a.fn.selectpicker.defaults={noneSelectedText:"",noneResultsText:"",countSelectedText:function(a,b){return 1==a?"... ({n})":"... ({n})"},maxOptionsText:function(a,b){return[1==a?"🛇":"🛇",1==b?"🛇":"🛇"]},selectAllText:"++",deselectAllText:"--",multipleSeparator:", "}}(a)});
\ No newline at end of file diff --git a/src/main/resources/js/bootstrap.config.js b/src/main/resources/js/bootstrap.config.js deleted file mode 100644 index 906942d1..00000000 --- a/src/main/resources/js/bootstrap.config.js +++ /dev/null @@ -1,64 +0,0 @@ -module.exports = { - - // Default for the style loading - styleLoader: 'style-loader!css-loader!less-loader', - - scripts: { - 'transition': true, - 'alert': true, - 'button': true, - 'carousel': true, - 'collapse': true, - 'dropdown': true, - 'modal': true, - 'tooltip': true, - 'popover': true, - 'scrollspy': true, - 'tab': true, - 'affix': true - }, - styles: { - "mixins": false, - - "normalize": false, - "print": false, - - "scaffolding": false, - "type": false, - "code": false, - "grid": false, - "tables": false, - "forms": false, - "buttons": false, - - "component-animations": false, - "glyphicons": false, - "dropdowns": false, - "button-groups": false, - "input-groups": false, - "navs": false, - "navbar": false, - "breadcrumbs": false, - "pagination": false, - "pager": false, - "labels": false, - "badges": false, - "jumbotron": false, - "thumbnails": false, - "alerts": false, - "progress-bars": false, - "media": false, - "list-group": false, - "panels": false, - "wells": false, - "close": false, - - "modals": false, - "tooltip": false, - "popovers": false, - "carousel": false, - - "utilities": false, - "responsive-utilities": false - } -}; diff --git a/src/main/resources/js/bootstrap.config.less b/src/main/resources/js/bootstrap.config.less deleted file mode 100644 index e69de29b..00000000 --- a/src/main/resources/js/bootstrap.config.less +++ /dev/null diff --git a/src/main/web/index.html b/src/main/web/index.html deleted file mode 100644 index 3cb55f61..00000000 --- a/src/main/web/index.html +++ /dev/null @@ -1,40 +0,0 @@ -<!DOCTYPE html> -<!-- - ~ 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. - --> -<html> -<head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <title>KVision</title> - <script type="text/javascript" src="main.bundle.js"></script> - <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> - <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> - <!--[if lt IE 9]> - <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script> - <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> - <![endif]--> -</head> -<body> -<div id="kvision"></div> -</body> -</html> |