aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/html/Tag.kt9
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/table/Cell.kt50
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt50
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/table/Row.kt39
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/table/Table.kt174
5 files changed, 321 insertions, 1 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt
index 33ef2cb7..897daa60 100644
--- a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt
@@ -65,7 +65,14 @@ enum class TAG(internal val tagName: String) {
VAR("var"),
SAMP("samp"),
SPAN("span"),
- LI("li")
+ LI("li"),
+
+ CAPTION("caption"),
+ THEAD("thead"),
+ TH("th"),
+ TBODY("tbody"),
+ TR("tr"),
+ TD("td")
}
/**
diff --git a/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt b/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt
new file mode 100644
index 00000000..ea59ed81
--- /dev/null
+++ b/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018. Robert Jaros
+ */
+package pl.treksoft.kvision.table
+
+import pl.treksoft.kvision.html.Align
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+
+/**
+ * HTML table cell component.
+ *
+ * @constructor
+ * @param text text content of the cell
+ * @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 Cell(
+ text: String? = null,
+ rich: Boolean = false,
+ align: Align? = null,
+ classes: Set<String> = setOf(),
+ init: (Cell.() -> Unit)? = null
+) : Tag(TAG.TD, text, rich, align, classes) {
+
+ init {
+ init?.invoke(this)
+ }
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Row.cell(
+ text: String? = null,
+ rich: Boolean = false,
+ align: Align? = null,
+ classes: Set<String> = setOf(), init: (Cell.() -> Unit)? = null
+ ): Cell {
+ val cell = Cell(text, rich, align, classes, init)
+ this.add(cell)
+ return cell
+ }
+ }
+
+}
diff --git a/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt b/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt
new file mode 100644
index 00000000..26ea24d2
--- /dev/null
+++ b/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018. Robert Jaros
+ */
+package pl.treksoft.kvision.table
+
+import pl.treksoft.kvision.html.Align
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+
+/**
+ * HTML table header cell component.
+ *
+ * @constructor
+ * @param text text content of the cell
+ * @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 HeaderCell(
+ text: String? = null,
+ rich: Boolean = false,
+ align: Align? = null,
+ classes: Set<String> = setOf(),
+ init: (HeaderCell.() -> Unit)? = null
+) : Tag(TAG.TH, text, rich, align, classes) {
+
+ init {
+ init?.invoke(this)
+ }
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Row.headerCell(
+ text: String? = null,
+ rich: Boolean = false,
+ align: Align? = null,
+ classes: Set<String> = setOf(), init: (HeaderCell.() -> Unit)? = null
+ ): HeaderCell {
+ val cell = HeaderCell(text, rich, align, classes, init)
+ this.add(cell)
+ return cell
+ }
+ }
+
+}
diff --git a/src/main/kotlin/pl/treksoft/kvision/table/Row.kt b/src/main/kotlin/pl/treksoft/kvision/table/Row.kt
new file mode 100644
index 00000000..d408f699
--- /dev/null
+++ b/src/main/kotlin/pl/treksoft/kvision/table/Row.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018. Robert Jaros
+ */
+package pl.treksoft.kvision.table
+
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+
+/**
+ * HTML table row component.
+ *
+ * @constructor
+ * @param classes a set of CSS class names
+ * @param init an initializer extension function
+ */
+open class Row(classes: Set<String> = setOf(), init: (Row.() -> Unit)? = null) : Tag(
+ TAG.TR, classes = classes
+) {
+
+ init {
+ init?.invoke(this)
+ }
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Table.row(
+ classes: Set<String> = setOf(), init: (Row.() -> Unit)? = null
+ ): Row {
+ val row = Row(classes, init)
+ this.add(row)
+ return row
+ }
+ }
+
+}
diff --git a/src/main/kotlin/pl/treksoft/kvision/table/Table.kt b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt
new file mode 100644
index 00000000..31a0913a
--- /dev/null
+++ b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2018. Robert Jaros
+ */
+package pl.treksoft.kvision.table
+
+import com.github.snabbdom.VNode
+import com.github.snabbdom.h
+import pl.treksoft.kvision.core.Component
+import pl.treksoft.kvision.core.Container
+import pl.treksoft.kvision.core.StringBoolPair
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+import pl.treksoft.kvision.panel.SimplePanel
+import pl.treksoft.kvision.utils.snClasses
+import pl.treksoft.kvision.utils.snOpt
+
+/**
+ * HTML table types.
+ */
+enum class TableType(internal val type: String) {
+ STRIPED("table-striped"),
+ BORDERED("table-bordered"),
+ HOVER("table-hover"),
+ CONDENSED("table-condensed")
+}
+
+/**
+ * HTML table component.
+ *
+ * @constructor
+ * @param headerNames a list of table headers names
+ * @param types a set of table types
+ * @param caption table caption
+ * @param responsive determines if the table is responsive
+ * @param classes a set of CSS class names
+ * @param init an initializer extension function
+ */
+open class Table(
+ headerNames: List<String>? = null,
+ types: Set<TableType> = setOf(), caption: String? = null, responsive: Boolean = false,
+ classes: Set<String> = setOf(), init: (Table.() -> Unit)? = null
+) : SimplePanel(classes + "table") {
+
+ /**
+ * Table headers names.
+ */
+ var headerNames by refreshOnUpdate(headerNames, { refreshHeaders() })
+ /**
+ * Table types.
+ */
+ var types by refreshOnUpdate(types)
+ /**
+ * Table caption.
+ */
+ var caption by refreshOnUpdate(caption)
+ /**
+ * Determines if the table is responsive.
+ */
+ var responsive by refreshOnUpdate(responsive)
+
+ private val theadRow = Tag(TAG.TR)
+ private val thead = Tag(TAG.THEAD).add(theadRow)
+ private val tbody = Tag(TAG.TBODY)
+
+ init {
+ refreshHeaders()
+ @Suppress("LeakingThis")
+ init?.invoke(this)
+ }
+
+ private fun refreshHeaders() {
+ theadRow.removeAll()
+ headerNames?.forEach {
+ theadRow.add(HeaderCell(it))
+ }
+ }
+
+ /**
+ * Adds new header cell to the table.
+ * @param cell header cell
+ * @return this table
+ */
+ fun addHeaderCell(cell: HeaderCell): Table {
+ theadRow.add(cell)
+ return this
+ }
+
+ /**
+ * Removes given header cell from the table.
+ * @param cell header cell
+ * @return this table
+ */
+ fun removeHeaderCell(cell: HeaderCell): Table {
+ theadRow.remove(cell)
+ return this
+ }
+
+ /**
+ * Removes all header cells from table.
+ * @return this table
+ */
+ fun removeHeaderCells(): Table {
+ theadRow.removeAll()
+ return this
+ }
+
+ override fun render(): VNode {
+ return if (responsive) {
+ val opt = snOpt {
+ `class` = snClasses(listOf("table-responsive" to true))
+ }
+ h("div", opt, arrayOf(render("table", childrenVNodes())))
+ } else {
+ render("table", childrenVNodes())
+ }
+ }
+
+ override fun childrenVNodes(): Array<VNode> {
+ val captionElement = caption?.let {
+ Tag(TAG.CAPTION, it)
+ }
+ return listOf(captionElement, thead, tbody).mapNotNull { it?.renderVNode() }.toTypedArray()
+ }
+
+ override fun getSnClass(): List<StringBoolPair> {
+ val cl = super.getSnClass().toMutableList()
+ types.forEach {
+ cl.add(it.type to true)
+ }
+ return cl
+ }
+
+ override fun add(child: Component): SimplePanel {
+ tbody.add(child)
+ return this
+ }
+
+ override fun addAll(children: List<Component>): SimplePanel {
+ tbody.addAll(children)
+ return this
+ }
+
+ override fun remove(child: Component): SimplePanel {
+ tbody.remove(child)
+ return this
+ }
+
+ override fun removeAll(): SimplePanel {
+ tbody.removeAll()
+ return this
+ }
+
+ override fun getChildren(): List<Component> {
+ return tbody.getChildren()
+ }
+
+ companion object {
+ /**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+ fun Container.table(
+ headerNames: List<String>? = null,
+ types: Set<TableType> = setOf(), caption: String? = null, responsive: Boolean = false,
+ classes: Set<String> = setOf(), init: (Table.() -> Unit)? = null
+ ): Table {
+ val table =
+ Table(headerNames, types, caption, responsive, classes, init)
+ this.add(table)
+ return table
+ }
+ }
+}