From 134cb687c4e05fd81a03b682505f9fb9d741a8d7 Mon Sep 17 00:00:00 2001 From: Robert Jaros Date: Sat, 9 May 2020 23:53:57 +0200 Subject: Add new className parameter to all DSL builder functions. --- .../pl/treksoft/kvision/form/time/DateTime.kt | 2 +- .../pl/treksoft/kvision/form/time/DateTimeInput.kt | 26 ++++++++++- .../treksoft/kvision/form/select/SelectRemote.kt | 2 +- .../kvision/form/select/SelectRemoteInput.kt | 7 ++- .../pl/treksoft/kvision/form/select/Select.kt | 2 +- .../pl/treksoft/kvision/form/select/SelectInput.kt | 24 +++++++++- .../treksoft/kvision/form/select/SelectOptGroup.kt | 18 ++++++-- .../treksoft/kvision/form/select/SelectOption.kt | 25 ++++++++--- .../pl/treksoft/kvision/form/spinner/Spinner.kt | 2 +- .../treksoft/kvision/form/spinner/SpinnerInput.kt | 31 ++++++++++++- .../kvision/form/text/TypeaheadRemoteInput.kt | 7 ++- .../treksoft/kvision/form/text/TypeaheadInput.kt | 16 ++++--- .../pl/treksoft/kvision/form/upload/Upload.kt | 2 +- .../pl/treksoft/kvision/form/upload/UploadInput.kt | 6 ++- .../pl/treksoft/kvision/dropdown/ContextMenu.kt | 7 ++- .../pl/treksoft/kvision/dropdown/DropDown.kt | 51 +++++++++++++++++----- .../kotlin/pl/treksoft/kvision/dropdown/Header.kt | 17 ++++++-- .../pl/treksoft/kvision/dropdown/Separator.kt | 15 +++++-- .../main/kotlin/pl/treksoft/kvision/navbar/Nav.kt | 26 ++++++++--- .../kotlin/pl/treksoft/kvision/navbar/NavForm.kt | 8 +++- .../kotlin/pl/treksoft/kvision/navbar/Navbar.kt | 19 ++++++-- .../treksoft/kvision/panel/ResponsiveGridPanel.kt | 7 ++- .../kotlin/pl/treksoft/kvision/panel/TabPanel.kt | 6 ++- .../pl/treksoft/kvision/progress/ProgressBar.kt | 15 ++++++- .../pl/treksoft/kvision/toolbar/ButtonGroup.kt | 14 ++++-- .../kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt | 7 ++- .../kotlin/pl/treksoft/kvision/window/Window.kt | 15 ++++++- .../main/kotlin/pl/treksoft/kvision/chart/Chart.kt | 8 ++-- .../main/kotlin/pl/treksoft/kvision/maps/Maps.kt | 6 ++- .../pl/treksoft/kvision/form/text/RichTextInput.kt | 8 +++- .../treksoft/kvision/tabulator/TabulatorRemote.kt | 7 ++- .../pl/treksoft/kvision/tabulator/Tabulator.kt | 17 +++++--- src/main/kotlin/pl/treksoft/kvision/core/Widget.kt | 30 ++++++++++--- .../pl/treksoft/kvision/core/WidgetWrapper.kt | 6 ++- .../kotlin/pl/treksoft/kvision/form/FieldLabel.kt | 9 ++-- .../kotlin/pl/treksoft/kvision/form/FormPanel.kt | 7 ++- .../treksoft/kvision/form/check/CheckBoxInput.kt | 7 ++- .../pl/treksoft/kvision/form/check/RadioGroup.kt | 2 +- .../pl/treksoft/kvision/form/check/RadioInput.kt | 7 ++- .../kotlin/pl/treksoft/kvision/form/range/Range.kt | 2 +- .../pl/treksoft/kvision/form/range/RangeInput.kt | 17 +++++++- .../treksoft/kvision/form/select/SimpleSelect.kt | 2 +- .../kvision/form/select/SimpleSelectInput.kt | 15 ++++++- .../pl/treksoft/kvision/form/text/AbstractText.kt | 2 +- .../pl/treksoft/kvision/form/text/TextAreaInput.kt | 9 +++- .../pl/treksoft/kvision/form/text/TextInput.kt | 8 +++- src/main/kotlin/pl/treksoft/kvision/html/Bold.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/Button.kt | 14 +++++- src/main/kotlin/pl/treksoft/kvision/html/Canvas.kt | 8 +++- .../kotlin/pl/treksoft/kvision/html/CustomTag.kt | 7 ++- src/main/kotlin/pl/treksoft/kvision/html/Div.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/Footer.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/H1.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/H2.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/H3.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/H4.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/H5.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/H6.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/Header.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/Iframe.kt | 17 +++++++- src/main/kotlin/pl/treksoft/kvision/html/Image.kt | 12 ++++- src/main/kotlin/pl/treksoft/kvision/html/Li.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/Link.kt | 33 ++++++++++++-- .../kotlin/pl/treksoft/kvision/html/ListTag.kt | 9 +++- src/main/kotlin/pl/treksoft/kvision/html/Main.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/Nav.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/Ol.kt | 7 ++- src/main/kotlin/pl/treksoft/kvision/html/P.kt | 6 ++- .../kotlin/pl/treksoft/kvision/html/Section.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/Span.kt | 6 ++- src/main/kotlin/pl/treksoft/kvision/html/Tag.kt | 13 +++++- src/main/kotlin/pl/treksoft/kvision/html/Ul.kt | 7 ++- .../kotlin/pl/treksoft/kvision/panel/DockPanel.kt | 14 +++++- .../pl/treksoft/kvision/panel/FieldsetPanel.kt | 6 ++- .../kotlin/pl/treksoft/kvision/panel/FlexPanel.kt | 9 +++- .../kotlin/pl/treksoft/kvision/panel/GridPanel.kt | 19 +++++++- .../kotlin/pl/treksoft/kvision/panel/HPanel.kt | 6 ++- .../pl/treksoft/kvision/panel/SimplePanel.kt | 9 +++- .../kotlin/pl/treksoft/kvision/panel/SplitPanel.kt | 7 ++- .../kotlin/pl/treksoft/kvision/panel/StackPanel.kt | 8 +++- .../kotlin/pl/treksoft/kvision/panel/VPanel.kt | 7 ++- src/main/kotlin/pl/treksoft/kvision/table/Cell.kt | 13 ++++-- .../kotlin/pl/treksoft/kvision/table/HeaderCell.kt | 7 ++- src/main/kotlin/pl/treksoft/kvision/table/Row.kt | 7 ++- src/main/kotlin/pl/treksoft/kvision/table/Table.kt | 11 ++++- src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt | 8 ++++ .../pl/treksoft/kvision/form/FieldLabelSpec.kt | 2 +- 87 files changed, 697 insertions(+), 205 deletions(-) diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt index aa3e77b2..68ec96a2 100644 --- a/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTime.kt @@ -196,7 +196,7 @@ open class DateTime( this.input.id = idc this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, setOf("control-label")) final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { diff --git a/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt index daeda692..967ca9db 100644 --- a/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt +++ b/kvision-modules/kvision-bootstrap-datetime/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt @@ -36,6 +36,7 @@ import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.types.toDateF import pl.treksoft.kvision.types.toStringF import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set import kotlin.js.Date internal const val DEFAULT_STEPPING = 5 @@ -78,10 +79,12 @@ open class DateTimeInput( input.value = value?.toStringF(format) refreshState() } + /** * Date/time format. */ var format by refreshOnUpdate(format) { refreshDatePicker() } + /** * The placeholder for the date/time input. */ @@ -90,6 +93,7 @@ open class DateTimeInput( set(value) { input.placeholder = value } + /** * The name attribute of the generated HTML input element. */ @@ -98,6 +102,7 @@ open class DateTimeInput( set(value) { input.name = value } + /** * Determines if the field is disabled. */ @@ -106,6 +111,7 @@ open class DateTimeInput( set(value) { input.disabled = value } + /** * Determines if the text input is automatically focused. */ @@ -114,6 +120,7 @@ open class DateTimeInput( set(value) { input.autofocus = value } + /** * Determines if the date/time input is read-only. */ @@ -122,6 +129,7 @@ open class DateTimeInput( set(value) { input.readonly = value } + /** * The size of the input. */ @@ -130,6 +138,7 @@ open class DateTimeInput( set(value) { input.size = value } + /** * The validation status of the input. */ @@ -139,46 +148,57 @@ open class DateTimeInput( input.validationStatus = value refresh() } + /** * Days of the week that should be disabled. Multiple values should be comma separated. */ var daysOfWeekDisabled by refreshOnUpdate(arrayOf()) { refreshDatePicker() } + /** * Determines if *Clear* button should be visible. */ var showClear by refreshOnUpdate(true) { refreshDatePicker() } + /** * Determines if *Close* button should be visible. */ var showClose by refreshOnUpdate(true) { refreshDatePicker() } + /** * Determines if *Today* button should be visible. */ var showTodayButton by refreshOnUpdate(true) { refreshDatePicker() } + /** * The increment used to build the hour view. */ var stepping by refreshOnUpdate(DEFAULT_STEPPING) { refreshDatePicker() } + /** * Prevents date selection before this date. */ var minDate: Date? by refreshOnUpdate { refreshDatePicker() } + /** * Prevents date selection after this date. */ var maxDate: Date? by refreshOnUpdate { refreshDatePicker() } + /** * Shows date and time pickers side by side. */ var sideBySide by refreshOnUpdate(false) { refreshDatePicker() } + /** * An array of enabled dates. */ var enabledDates by refreshOnUpdate(arrayOf()) { refreshDatePicker() } + /** * An array of disabled dates. */ var disabledDates by refreshOnUpdate(arrayOf()) { refreshDatePicker() } + /** * Allow date picker for readonly component. */ @@ -392,10 +412,12 @@ open class DateTimeInput( * 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 = setOf(), + value: Date? = null, format: String = "YYYY-MM-DD HH:mm", + classes: Set? = null, + className: String? = null, init: (DateTimeInput.() -> Unit)? = null ): DateTimeInput { - val dateTimeInput = DateTimeInput(value, format, classes).apply { init?.invoke(this) } + val dateTimeInput = DateTimeInput(value, format, classes ?: className.set).apply { init?.invoke(this) } this.add(dateTimeInput) return dateTimeInput } diff --git a/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt index dbd0aa70..b4e4738c 100644 --- a/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt +++ b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemote.kt @@ -166,7 +166,7 @@ open class SelectRemote( this.id = idc this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, setOf("control-label")) final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { diff --git a/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt index e7fd384c..b6319a6b 100644 --- a/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt +++ b/kvision-modules/kvision-bootstrap-select-remote/src/main/kotlin/pl/treksoft/kvision/form/select/SelectRemoteInput.kt @@ -36,6 +36,7 @@ import pl.treksoft.kvision.remote.KVServiceManager import pl.treksoft.kvision.remote.RemoteOption import pl.treksoft.kvision.utils.JSON import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set import kotlin.browser.window external fun decodeURIComponent(encodedURI: String): String @@ -197,7 +198,9 @@ fun Container.selectRemoteInput( multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, preload: Boolean = false, - classes: Set = setOf(), init: (SelectRemoteInput.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (SelectRemoteInput.() -> Unit)? = null ): SelectRemoteInput { val selectRemoteInput = SelectRemoteInput( @@ -208,7 +211,7 @@ fun Container.selectRemoteInput( multiple, ajaxOptions, preload, - classes + classes ?: className.set ).apply { init?.invoke(this) } diff --git a/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt index b3f5e1c1..4ffece7d 100644 --- a/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/Select.kt @@ -183,7 +183,7 @@ open class Select( this.id = idc this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, setOf("control-label")) final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { diff --git a/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt index 01b35ed2..ced0945d 100644 --- a/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt @@ -35,6 +35,7 @@ import pl.treksoft.kvision.html.ButtonStyle import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.asString import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set /** * Select width types. See [Bootstrap Select width](http://silviomoreto.github.io/bootstrap-select/examples/#width). @@ -77,18 +78,22 @@ open class SelectInput( * A list of options (value to label pairs) for the select control. */ 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. */ override var name: String? by refreshOnUpdate() + /** * Determines if multiple value selection is allowed. */ var multiple by refreshOnUpdate(multiple) + /** * Additional options for remote (AJAX) data source. */ @@ -98,50 +103,62 @@ open class SelectInput( } 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() + /** * The dropdown align of the select control. */ var dropdownAlign by refreshOnUpdate(SelectDropdownAlign.LEFT) + /** * Determines if an empty option is automatically generated. */ var emptyOption by refreshOnUpdate(false) { setChildrenFromOptions() } + /** * Determines if the field is disabled. */ override var disabled by refreshOnUpdate(false) + /** * Determines if the select is automatically focused. */ var autofocus: Boolean? by refreshOnUpdate() + /** * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** * The validation status of the input. */ @@ -389,9 +406,12 @@ open class SelectInput( fun Container.selectInput( options: List? = null, value: String? = null, multiple: Boolean = false, ajaxOptions: AjaxOptions? = null, - classes: Set = setOf(), init: (SelectInput.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (SelectInput.() -> Unit)? = null ): SelectInput { - val selectInput = SelectInput(options, value, multiple, ajaxOptions, classes).apply { init?.invoke(this) } + val selectInput = + SelectInput(options, value, multiple, ajaxOptions, classes ?: className.set).apply { init?.invoke(this) } this.add(selectInput) return selectInput } diff --git a/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt index 7893f891..a265c35b 100644 --- a/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt @@ -24,6 +24,7 @@ package pl.treksoft.kvision.form.select import com.github.snabbdom.VNode import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.set /** * The helper container for adding option groups to [Select]. @@ -46,14 +47,17 @@ open class SelectOptGroup( * 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. */ @@ -97,10 +101,13 @@ open class SelectOptGroup( */ fun Select.selectOptGroup( label: String, options: List? = null, maxOptions: Int? = null, - disabled: Boolean = false, classes: Set = setOf(), init: (SelectOptGroup.() -> Unit)? = null + disabled: Boolean = false, + classes: Set? = null, + className: String? = null, + init: (SelectOptGroup.() -> Unit)? = null ): SelectOptGroup { val selectOptGroup = - SelectOptGroup(label, options, maxOptions, disabled, classes).apply { init?.invoke(this) } + SelectOptGroup(label, options, maxOptions, disabled, classes ?: className.set).apply { init?.invoke(this) } this.add(selectOptGroup) return selectOptGroup } @@ -112,10 +119,13 @@ fun Select.selectOptGroup( */ fun SelectInput.selectOptGroup( label: String, options: List? = null, maxOptions: Int? = null, - disabled: Boolean = false, classes: Set = setOf(), init: (SelectOptGroup.() -> Unit)? = null + disabled: Boolean = false, + classes: Set? = null, + className: String? = null, + init: (SelectOptGroup.() -> Unit)? = null ): SelectOptGroup { val selectOptGroup = - SelectOptGroup(label, options, maxOptions, disabled, classes).apply { init?.invoke(this) } + SelectOptGroup(label, options, maxOptions, disabled, classes ?: className.set).apply { init?.invoke(this) } this.add(selectOptGroup) return selectOptGroup } diff --git a/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt index a9c7eda5..1c8689c0 100644 --- a/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt +++ b/kvision-modules/kvision-bootstrap-select/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt @@ -24,6 +24,7 @@ package pl.treksoft.kvision.form.select import com.github.snabbdom.VNode import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.utils.set /** * The helper component for adding options to [Select] or [SelectOptGroup]. @@ -47,26 +48,32 @@ open class SelectOption( * 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) + /** * Determines if the option is selected. */ @@ -114,10 +121,12 @@ open class SelectOption( fun Select.selectOption( value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, - classes: Set = setOf(), init: (SelectOption.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (SelectOption.() -> Unit)? = null ): SelectOption { val selectOption = - SelectOption(value, label, subtext, icon, divider, disabled, selected, classes).apply { + SelectOption(value, label, subtext, icon, divider, disabled, selected, classes ?: className.set).apply { init?.invoke( this ) @@ -134,10 +143,12 @@ fun Select.selectOption( fun SelectInput.selectOption( value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, - classes: Set = setOf(), init: (SelectOption.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (SelectOption.() -> Unit)? = null ): SelectOption { val selectOption = - SelectOption(value, label, subtext, icon, divider, disabled, selected, classes).apply { + SelectOption(value, label, subtext, icon, divider, disabled, selected, classes ?: className.set).apply { init?.invoke( this ) @@ -154,10 +165,12 @@ fun SelectInput.selectOption( fun SelectOptGroup.selectOption( value: String? = null, label: String? = null, subtext: String? = null, icon: String? = null, divider: Boolean = false, disabled: Boolean = false, selected: Boolean = false, - classes: Set = setOf(), init: (SelectOption.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (SelectOption.() -> Unit)? = null ): SelectOption { val selectOption = - SelectOption(value, label, subtext, icon, divider, disabled, selected, classes).apply { + SelectOption(value, label, subtext, icon, divider, disabled, selected, classes ?: className.set).apply { init?.invoke( this ) diff --git a/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt index a842a37f..3901cc4f 100644 --- a/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt @@ -180,7 +180,7 @@ open class Spinner( this.id = idc this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, setOf("control-label")) final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { diff --git a/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt index 3a52fed2..98b7be62 100644 --- a/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt +++ b/kvision-modules/kvision-bootstrap-spinner/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt @@ -32,6 +32,7 @@ import pl.treksoft.kvision.form.InputSize import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.html.ButtonStyle import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set /** * Spinner buttons layout types. @@ -80,6 +81,7 @@ open class SpinnerInput( * Spinner value. */ var value by refreshOnUpdate(value) { refreshState() } + /** * The value attribute of the generated HTML input element. * @@ -87,54 +89,67 @@ open class SpinnerInput( * 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 force rounding type. */ var forceType by refreshOnUpdate(forceType) { refreshSpinner() } + /** * The style of the up/down buttons. */ var buttonStyle by refreshOnUpdate(buttonStyle) { refreshSpinner() } + /** * The placeholder for the spinner input. */ var placeholder: String? by refreshOnUpdate() + /** * The name attribute of the generated HTML input element. */ override var name: String? by refreshOnUpdate() + /** * Determines if the field is disabled. */ override 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. */ override var size: InputSize? by refreshOnUpdate() + /** * The validation status of the input. */ @@ -323,11 +338,23 @@ open class SpinnerInput( fun Container.spinnerInput( value: Number? = null, min: Number? = null, max: Number? = null, step: Number = DEFAULT_STEP, decimals: Int = 0, buttonsType: ButtonsType = ButtonsType.VERTICAL, - forceType: ForceType = ForceType.NONE, buttonStyle: ButtonStyle? = null, classes: Set = setOf(), + forceType: ForceType = ForceType.NONE, buttonStyle: ButtonStyle? = null, + classes: Set? = null, + className: String? = null, init: (SpinnerInput.() -> Unit)? = null ): SpinnerInput { val spinnerInput = - SpinnerInput(value, min, max, step, decimals, buttonsType, forceType, buttonStyle, classes).apply { + SpinnerInput( + value, + min, + max, + step, + decimals, + buttonsType, + forceType, + buttonStyle, + classes ?: className.set + ).apply { init?.invoke( this ) diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt b/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt index 42412ae4..0693756b 100644 --- a/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt +++ b/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt @@ -30,6 +30,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.remote.JsonRpcRequest import pl.treksoft.kvision.remote.KVServiceManager import pl.treksoft.kvision.utils.JSON +import pl.treksoft.kvision.utils.set import kotlin.browser.window /** @@ -86,12 +87,14 @@ fun Container.typeaheadRemoteInput( function: suspend T.(String?, String?) -> List, stateFunction: (() -> String)? = null, items: Int? = 8, minLength: Int = 1, delay: Int = 0, - type: TextInputType = TextInputType.TEXT, value: String? = null, classes: Set = setOf(), + type: TextInputType = TextInputType.TEXT, value: String? = null, + classes: Set? = null, + className: String? = null, init: (TypeaheadRemoteInput.() -> Unit)? = null ): TypeaheadRemoteInput { val typeaheadRemoteInput = TypeaheadRemoteInput( - serviceManager, function, stateFunction, items, minLength, delay, type, value, classes + serviceManager, function, stateFunction, items, minLength, delay, type, value, classes ?: className.set ).apply { init?.invoke(this) } diff --git a/kvision-modules/kvision-bootstrap-typeahead/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadInput.kt b/kvision-modules/kvision-bootstrap-typeahead/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadInput.kt index bf0622f1..104c7f8d 100644 --- a/kvision-modules/kvision-bootstrap-typeahead/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadInput.kt +++ b/kvision-modules/kvision-bootstrap-typeahead/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadInput.kt @@ -26,6 +26,7 @@ import pl.treksoft.jquery.JQueryXHR import pl.treksoft.jquery.jQuery import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set enum class ShowHintOnFocus { NO, @@ -183,14 +184,17 @@ open class TypeaheadInput( fun Container.typeaheadInput( options: List? = null, taAjaxOptions: TaAjaxOptions? = null, items: Int? = 8, minLength: Int = 1, delay: Int = 0, - type: TextInputType = TextInputType.TEXT, value: String? = null, classes: Set = setOf(), + type: TextInputType = TextInputType.TEXT, value: String? = null, + classes: Set? = null, + className: String? = null, init: (TypeaheadInput.() -> Unit)? = null ): TypeaheadInput { - val typeaheadInput = TypeaheadInput(options, taAjaxOptions, items, minLength, delay, type, value, classes).apply { - init?.invoke( - this - ) - } + val typeaheadInput = + TypeaheadInput(options, taAjaxOptions, items, minLength, delay, type, value, classes ?: className.set).apply { + init?.invoke( + this + ) + } this.add(typeaheadInput) return typeaheadInput } diff --git a/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt index 96672587..1f28f252 100644 --- a/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/Upload.kt @@ -215,7 +215,7 @@ open class Upload( this.id = idc this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, setOf("control-label")) final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { diff --git a/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt index 5bdaad9b..3930ace2 100644 --- a/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt +++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt @@ -36,6 +36,7 @@ import pl.treksoft.kvision.i18n.I18n import pl.treksoft.kvision.types.KFile import pl.treksoft.kvision.utils.getContent import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set import kotlin.reflect.KProperty1 /** @@ -369,10 +370,11 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla fun Container.uploadInput( uploadUrl: String? = null, multiple: Boolean = false, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (UploadInput.() -> Unit)? = null ): UploadInput { - val uploadInput = UploadInput(uploadUrl, multiple, classes).apply { + val uploadInput = UploadInput(uploadUrl, multiple, classes ?: className.set).apply { init?.invoke( this ) diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt index 656b63b5..4d4a579c 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/ContextMenu.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.utils.px +import pl.treksoft.kvision.utils.set /** * Context menu component. @@ -103,9 +104,11 @@ fun Widget.setContextMenu(contextMenu: ContextMenu): Widget { */ fun Widget.contextMenu( fixedPosition: Boolean = false, - classes: Set = setOf(), init: (ContextMenu.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (ContextMenu.() -> Unit)? = null ): ContextMenu { - val contextMenu = ContextMenu(this, fixedPosition, classes).apply { init?.invoke(this) } + val contextMenu = ContextMenu(this, fixedPosition, classes ?: className.set).apply { init?.invoke(this) } this.setContextMenu(contextMenu) return contextMenu } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt index 3fa6cd36..ed9a917c 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt @@ -35,6 +35,7 @@ import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.html.Link import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set /** * Useful options for use in DropDown's *elements* parameter. @@ -84,6 +85,7 @@ open class DropDown( button.text = value } private var elements by refreshOnUpdate(elements) { setChildrenFromElements() } + /** * The icon of the dropdown button. */ @@ -92,6 +94,7 @@ open class DropDown( set(value) { button.icon = value } + /** * The style of the dropdown button. */ @@ -100,6 +103,7 @@ open class DropDown( set(value) { button.style = value } + /** * The size of the dropdown button. */ @@ -108,6 +112,7 @@ open class DropDown( set(value) { button.size = value } + /** * Determines if the dropdown button takes all the space horizontally. */ @@ -116,6 +121,7 @@ open class DropDown( set(value) { button.block = value } + /** * Determines if the dropdown is disabled. */ @@ -124,6 +130,7 @@ open class DropDown( set(value) { button.disabled = value } + /** * The image on the dropdown button. */ @@ -132,10 +139,12 @@ open class DropDown( set(value) { button.image = value } + /** * The direction of the dropdown. */ var direction by refreshOnUpdate(direction) + /** * Width of the dropdown button. */ @@ -254,7 +263,9 @@ fun Container.dropDown( text: String, elements: List? = null, icon: String? = null, style: ButtonStyle = ButtonStyle.PRIMARY, direction: Direction = Direction.DROPDOWN, disabled: Boolean = false, forNavbar: Boolean = false, forDropDown: Boolean = false, - classes: Set = setOf(), init: (DropDown.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (DropDown.() -> Unit)? = null ): DropDown { val dropDown = DropDown( @@ -266,7 +277,7 @@ fun Container.dropDown( disabled, forNavbar, forDropDown, - classes + classes ?: className.set ).apply { init?.invoke(this) } this.add(dropDown) return dropDown @@ -279,9 +290,11 @@ fun Container.dropDown( */ fun DropDown.ddLink( label: String, url: String? = null, icon: String? = null, image: ResString? = null, - classes: Set = setOf(), init: (Link.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Link.() -> Unit)? = null ): Link { - val link = Link(label, url, icon, image, classes + "dropdown-item").apply { + val link = Link(label, url, icon, image, null, true, (classes ?: className.set) + "dropdown-item").apply { init?.invoke(this) } this.add(link) @@ -295,9 +308,11 @@ fun DropDown.ddLink( */ fun ContextMenu.cmLink( label: String, url: String? = null, icon: String? = null, image: ResString? = null, - classes: Set = setOf(), init: (Link.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Link.() -> Unit)? = null ): Link { - val link = Link(label, url, icon, image, classes + "dropdown-item").apply { + val link = Link(label, url, icon, image, null, true, (classes ?: className.set) + "dropdown-item").apply { init?.invoke(this) } this.add(link) @@ -311,9 +326,17 @@ fun ContextMenu.cmLink( */ fun DropDown.ddLinkDisabled( label: String, icon: String? = null, image: ResString? = null, - classes: Set = setOf(), init: (Link.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Link.() -> Unit)? = null ): Link { - val link = Link(label, "javascript:void(0)", icon, image, classes + "dropdown-item" + "disabled").apply { + val link = Link( + label, + "javascript:void(0)", + icon, + image, null, true, + (classes ?: className.set) + "dropdown-item" + "disabled" + ).apply { tabindex = -1 setAttribute("aria-disabled", "true") init?.invoke(this) @@ -329,9 +352,17 @@ fun DropDown.ddLinkDisabled( */ fun ContextMenu.cmLinkDisabled( label: String, icon: String? = null, image: ResString? = null, - classes: Set = setOf(), init: (Link.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Link.() -> Unit)? = null ): Link { - val link = Link(label, "javascript:void(0)", icon, image, classes + "dropdown-item" + "disabled").apply { + val link = Link( + label, + "javascript:void(0)", + icon, + image, null, true, + (classes ?: className.set) + "dropdown-item" + "disabled" + ).apply { tabindex = -1 setAttribute("aria-disabled", "true") init?.invoke(this) diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt index b88a5955..1d489afc 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Header.kt @@ -23,6 +23,7 @@ package pl.treksoft.kvision.dropdown import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.utils.set /** * Menu header component. @@ -39,8 +40,12 @@ open class Header(content: String? = null, classes: Set = setOf()) : * * It takes the same parameters as the constructor of the built component. */ -fun ContextMenu.header(content: String? = null, classes: Set = setOf()): Header { - val header = Header(content, classes) +fun ContextMenu.header( + content: String? = null, + classes: Set? = null, + className: String? = null +): Header { + val header = Header(content, classes ?: className.set) this.add(header) return header } @@ -50,8 +55,12 @@ fun ContextMenu.header(content: String? = null, classes: Set = setOf()): * * It takes the same parameters as the constructor of the built component. */ -fun DropDown.header(content: String? = null, classes: Set = setOf()): Header { - val header = Header(content, classes) +fun DropDown.header( + content: String? = null, + classes: Set? = null, + className: String? = null +): Header { + val header = Header(content, classes ?: className.set) this.add(header) return header } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt index 62abe588..f5d289f6 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/dropdown/Separator.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.dropdown import pl.treksoft.kvision.html.Div +import pl.treksoft.kvision.utils.set /** * Menu separator component. @@ -36,8 +37,11 @@ open class Separator(classes: Set = setOf()) : Div(classes = classes + " * * It takes the same parameters as the constructor of the built component. */ -fun ContextMenu.separator(classes: Set = setOf()): Separator { - val separator = Separator(classes) +fun ContextMenu.separator( + classes: Set? = null, + className: String? = null +): Separator { + val separator = Separator(classes ?: className.set) this.add(separator) return separator } @@ -47,8 +51,11 @@ fun ContextMenu.separator(classes: Set = setOf()): Separator { * * It takes the same parameters as the constructor of the built component. */ -fun DropDown.separator(classes: Set = setOf()): Separator { - val separator = Separator(classes) +fun DropDown.separator( + classes: Set? = null, + className: String? = null +): Separator { + val separator = Separator(classes ?: className.set) this.add(separator) return separator } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt index 1254e0c9..98383141 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Nav.kt @@ -25,6 +25,7 @@ import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.html.Link +import pl.treksoft.kvision.utils.set /** * The Bootstrap Nav container. @@ -63,9 +64,12 @@ open class Nav(rightAlign: Boolean = false, classes: Set = setOf(), init * It takes the same parameters as the constructor of the built component. */ fun Navbar.nav( - rightAlign: Boolean = false, classes: Set = setOf(), init: (Nav.() -> Unit)? = null + rightAlign: Boolean = false, + classes: Set? = null, + className: String? = null, + init: (Nav.() -> Unit)? = null ): Nav { - val nav = Nav(rightAlign, classes).apply { init?.invoke(this) } + val nav = Nav(rightAlign, classes ?: className.set).apply { init?.invoke(this) } this.add(nav) return nav } @@ -77,9 +81,11 @@ fun Navbar.nav( */ fun Nav.navLink( label: String, url: String? = null, icon: String? = null, image: ResString? = null, - classes: Set = setOf(), init: (Link.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Link.() -> Unit)? = null ): Link { - val link = Link(label, url, icon, image, classes + "nav-item" + "nav-link").apply { + val link = Link(label, url, icon, image, null, true, (classes ?: className.set) + "nav-item" + "nav-link").apply { init?.invoke(this) } this.add(link) @@ -93,10 +99,18 @@ fun Nav.navLink( */ fun Nav.navLinkDisabled( label: String, icon: String? = null, image: ResString? = null, - classes: Set = setOf(), init: (Link.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Link.() -> Unit)? = null ): Link { val link = - Link(label, "javascript:void(0)", icon, image, classes + "nav-item" + "nav-link" + "disabled").apply { + Link( + label, + "javascript:void(0)", + icon, + image, null, true, + (classes ?: className.set) + "nav-item" + "nav-link" + "disabled" + ).apply { tabindex = -1 setAttribute("aria-disabled", "true") init?.invoke(this) diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt index 6cbf6274..37bd566e 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/NavForm.kt @@ -24,6 +24,7 @@ package pl.treksoft.kvision.navbar import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.utils.set /** * The Bootstrap Nav form container. @@ -62,9 +63,12 @@ open class NavForm(rightAlign: Boolean = false, classes: Set = setOf(), * It takes the same parameters as the constructor of the built component. */ fun Navbar.navForm( - rightAlign: Boolean = false, classes: Set = setOf(), init: (NavForm.() -> Unit)? = null + rightAlign: Boolean = false, + classes: Set? = null, + className: String? = null, + init: (NavForm.() -> Unit)? = null ): NavForm { - val navForm = NavForm(rightAlign, classes).apply { init?.invoke(this) } + val navForm = NavForm(rightAlign, classes ?: className.set).apply { init?.invoke(this) } this.add(navForm) return navForm } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt index 81e061e8..6ba85b63 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/navbar/Navbar.kt @@ -32,6 +32,7 @@ import pl.treksoft.kvision.html.Link import pl.treksoft.kvision.html.Span import pl.treksoft.kvision.html.span import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.set /** * Navbar types. @@ -99,6 +100,7 @@ open class Navbar( brandLink.hide() } } + /** * The navbar header link. */ @@ -112,14 +114,17 @@ open class Navbar( * The navbar type. */ var type by refreshOnUpdate(type) + /** * The navbar responsive behavior. */ var expand by refreshOnUpdate(expand) + /** * The navbar color. */ var nColor by refreshOnUpdate(nColor) + /** * The navbar background color. */ @@ -215,15 +220,21 @@ fun Container.navbar( nColor: NavbarColor = NavbarColor.LIGHT, bgColor: BsBgColor = BsBgColor.LIGHT, collapseOnClick: Boolean = false, - classes: Set = setOf(), init: (Navbar.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Navbar.() -> Unit)? = null ): Navbar { - val navbar = Navbar(label, link, type, expand, nColor, bgColor, collapseOnClick, classes, init) + val navbar = Navbar(label, link, type, expand, nColor, bgColor, collapseOnClick, classes ?: className.set, init) this.add(navbar) return navbar } -fun Navbar.navText(label: String, classes: Set = setOf()): Span { - val text = Span(label, classes = classes + "navbar-text") +fun Navbar.navText( + label: String, + classes: Set? = null, + className: String? = null +): Span { + val text = Span(label, classes = (classes ?: className.set) + "navbar-text") this.add(text) return text } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt index ec4cbc29..9d21f61f 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.WidgetWrapper import pl.treksoft.kvision.html.Align import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.utils.set /** * Bootstrap grid sizes. @@ -175,9 +176,11 @@ open class ResponsiveGridPanel( fun Container.responsiveGridPanel( gridSize: GridSize = GridSize.MD, rows: Int = 0, cols: Int = 0, align: Align? = null, - classes: Set = setOf(), init: (ResponsiveGridPanel.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (ResponsiveGridPanel.() -> Unit)? = null ): ResponsiveGridPanel { - val responsiveGridPanel = ResponsiveGridPanel(gridSize, rows, cols, align, classes, init) + val responsiveGridPanel = ResponsiveGridPanel(gridSize, rows, cols, align, classes ?: className.set, init) this.add(responsiveGridPanel) return responsiveGridPanel } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt index 36967e2b..3b2accad 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt @@ -31,6 +31,7 @@ import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.html.link import pl.treksoft.kvision.routing.routing import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set import pl.treksoft.kvision.html.icon as cicon /** @@ -273,10 +274,11 @@ fun Container.tabPanel( tabPosition: TabPosition = TabPosition.TOP, sideTabSize: SideTabSize = SideTabSize.SIZE_3, scrollableTabs: Boolean = false, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (TabPanel.() -> Unit)? = null ): TabPanel { - val tabPanel = TabPanel(tabPosition, sideTabSize, scrollableTabs, classes, init) + val tabPanel = TabPanel(tabPosition, sideTabSize, scrollableTabs, classes ?: className.set, init) this.add(tabPanel) return tabPanel } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt index 45ea316c..f9dd0617 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/progress/ProgressBar.kt @@ -24,6 +24,7 @@ package pl.treksoft.kvision.progress import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.html.Align import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.set /** * The Bootstrap progress bar. @@ -57,6 +58,7 @@ open class ProgressBar( set(value) { indicator.progress = value } + /** * The minimal progress. */ @@ -65,6 +67,7 @@ open class ProgressBar( set(value) { indicator.min = value } + /** * The maximal progress. */ @@ -73,6 +76,7 @@ open class ProgressBar( set(value) { indicator.max = value } + /** * The style of the progress bar. */ @@ -81,6 +85,7 @@ open class ProgressBar( set(value) { indicator.style = value } + /** * Determines if the progress bar is striped. */ @@ -89,6 +94,7 @@ open class ProgressBar( set(value) { indicator.striped = value } + /** * Determines if the progress bar is animated. */ @@ -97,6 +103,7 @@ open class ProgressBar( set(value) { indicator.animated = value } + /** * Text content of the progress bar. */ @@ -105,6 +112,7 @@ open class ProgressBar( set(value) { indicator.content = value } + /** * Determines if [content] can contain HTML code. */ @@ -113,6 +121,7 @@ open class ProgressBar( set(value) { indicator.rich = value } + /** * Text align of the progress bar. */ @@ -141,7 +150,9 @@ fun Container.progressBar( progress: Int, min: Int = DEFAULT_MIN, max: Int = DEFAULT_MAX, style: ProgressBarStyle? = null, striped: Boolean = false, animated: Boolean = false, content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), init: (ProgressBar.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (ProgressBar.() -> Unit)? = null ): ProgressBar { val progressBar = ProgressBar( progress, @@ -153,7 +164,7 @@ fun Container.progressBar( content, rich, align, - classes + classes ?: className.set ).apply { init?.invoke(this) } this.add(progressBar) return progressBar diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt index 5d871a1c..70652fb7 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/ButtonGroup.kt @@ -25,6 +25,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.px +import pl.treksoft.kvision.utils.set /** * Button group sizes. @@ -52,6 +53,7 @@ open class ButtonGroup( * Button group size. */ var size by refreshOnUpdate(size) + /** * Vertical alignment. */ @@ -84,9 +86,11 @@ open class ButtonGroup( */ fun Container.buttonGroup( size: ButtonGroupSize? = null, vertical: Boolean = false, - classes: Set = setOf(), init: (ButtonGroup.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (ButtonGroup.() -> Unit)? = null ): ButtonGroup { - val group = ButtonGroup(size, vertical, classes).apply { init?.invoke(this) } + val group = ButtonGroup(size, vertical, classes ?: className.set).apply { init?.invoke(this) } this.add(group) return group } @@ -97,9 +101,11 @@ fun Container.buttonGroup( * It creates button groups with size and vertical parameters of the toolbar. */ fun Toolbar.buttonGroup( - classes: Set = setOf(), init: (ButtonGroup.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (ButtonGroup.() -> Unit)? = null ): ButtonGroup { - val group = ButtonGroup(this.size, this.vertical, classes).apply { + val group = ButtonGroup(this.size, this.vertical, classes ?: className.set).apply { marginRight = this@buttonGroup.spacing.px init?.invoke(this) } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt index b942d1d5..eefd10b1 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/toolbar/Toolbar.kt @@ -23,6 +23,7 @@ package pl.treksoft.kvision.toolbar import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.set /** * The Bootstrap toolbar. @@ -53,9 +54,11 @@ open class Toolbar( */ fun Container.toolbar( size: ButtonGroupSize? = null, spacing: Int = 2, vertical: Boolean = false, - classes: Set = setOf(), init: (Toolbar.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Toolbar.() -> Unit)? = null ): Toolbar { - val toolbar = Toolbar(size, spacing, vertical, classes).apply { init?.invoke(this) } + val toolbar = Toolbar(size, spacing, vertical, classes ?: className.set).apply { init?.invoke(this) } this.add(toolbar) return toolbar } diff --git a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt index b34de18d..0cceb672 100644 --- a/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt +++ b/kvision-modules/kvision-bootstrap/src/main/kotlin/pl/treksoft/kvision/window/Window.kt @@ -39,6 +39,7 @@ import pl.treksoft.kvision.modal.CloseIcon import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.utils.obj import pl.treksoft.kvision.utils.px +import pl.treksoft.kvision.utils.set internal const val DEFAULT_Z_INDEX = 900 internal const val WINDOW_HEADER_HEIGHT = 40 @@ -84,6 +85,7 @@ open class Window( captionTag.content = value checkHeaderVisibility() } + /** * Window content width. */ @@ -92,6 +94,7 @@ open class Window( set(value) { width = value } + /** * Window content height. */ @@ -100,6 +103,7 @@ open class Window( set(value) { content.height = value } + /** * Window content height. */ @@ -108,14 +112,17 @@ open class Window( set(value) { content.overflow = 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. */ @@ -125,6 +132,7 @@ open class Window( closeIcon.visible = value checkHeaderVisibility() } + /** * Determines if Maximize button is visible. */ @@ -134,6 +142,7 @@ open class Window( maximizeIcon.visible = value checkHeaderVisibility() } + /** * Determines if Maximize button is visible. */ @@ -143,6 +152,7 @@ open class Window( minimizeIcon.visible = value checkHeaderVisibility() } + /** * Window icon. */ @@ -426,7 +436,8 @@ fun Container.window( maximizeButton: Boolean = false, minimizeButton: Boolean = false, icon: String? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Window.() -> Unit)? = null ): Window { val window = @@ -440,7 +451,7 @@ fun Container.window( maximizeButton, minimizeButton, icon, - classes, + classes ?: className.set, init ) this.add(window) diff --git a/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/chart/Chart.kt b/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/chart/Chart.kt index 55718918..30ce529b 100644 --- a/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/chart/Chart.kt +++ b/kvision-modules/kvision-chart/src/main/kotlin/pl/treksoft/kvision/chart/Chart.kt @@ -24,9 +24,10 @@ package pl.treksoft.kvision.chart import com.github.snabbdom.VNode import pl.treksoft.kvision.chart.js.Chart.ChartConfiguration import pl.treksoft.kvision.chart.js.PluginServiceGlobalRegistration -import pl.treksoft.kvision.chart.js.Chart as JsChart import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.utils.set +import pl.treksoft.kvision.chart.js.Chart as JsChart /** * Chart component. @@ -133,10 +134,11 @@ fun Container.chart( configuration: Configuration, chartWidth: Int? = null, chartHeight: Int? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Chart.() -> Unit)? = null ): Chart { - val chart = Chart(configuration, chartWidth, chartHeight, classes).apply { init?.invoke(this) } + val chart = Chart(configuration, chartWidth, chartHeight, classes ?: className.set).apply { init?.invoke(this) } this.add(chart) return chart } diff --git a/kvision-modules/kvision-maps/src/main/kotlin/pl/treksoft/kvision/maps/Maps.kt b/kvision-modules/kvision-maps/src/main/kotlin/pl/treksoft/kvision/maps/Maps.kt index cb98fb8a..b76300c8 100644 --- a/kvision-modules/kvision-maps/src/main/kotlin/pl/treksoft/kvision/maps/Maps.kt +++ b/kvision-modules/kvision-maps/src/main/kotlin/pl/treksoft/kvision/maps/Maps.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.KVManagerMaps import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set /** * Maps component. @@ -90,10 +91,11 @@ fun Container.maps( lng: Number, zoom: Number, showMarker: Boolean = false, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Maps.() -> Unit)? = null ): Maps { - val maps = Maps(lat, lng, zoom, showMarker, classes, init) + val maps = Maps(lat, lng, zoom, showMarker, classes ?: className.set, init) this.add(maps) return maps } diff --git a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt index 8b58e272..fc7957ca 100644 --- a/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt +++ b/kvision-modules/kvision-richtext/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt @@ -25,6 +25,7 @@ import com.github.snabbdom.VNode import pl.treksoft.jquery.jQuery import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.utils.set import kotlin.browser.document /** @@ -122,9 +123,12 @@ open class RichTextInput(value: String? = null, classes: Set = setOf()) * It takes the same parameters as the constructor of the built component. */ fun Container.richTextInput( - value: String? = null, classes: Set = setOf(), init: (RichTextInput.() -> Unit)? = null + value: String? = null, + classes: Set? = null, + className: String? = null, + init: (RichTextInput.() -> Unit)? = null ): RichTextInput { - val richTextInput = RichTextInput(value, classes).apply { init?.invoke(this) } + val richTextInput = RichTextInput(value, classes ?: className.set).apply { init?.invoke(this) } this.add(richTextInput) return richTextInput } diff --git a/kvision-modules/kvision-tabulator-remote/src/main/kotlin/pl/treksoft/kvision/tabulator/TabulatorRemote.kt b/kvision-modules/kvision-tabulator-remote/src/main/kotlin/pl/treksoft/kvision/tabulator/TabulatorRemote.kt index c9e8e208..e4473ed8 100644 --- a/kvision-modules/kvision-tabulator-remote/src/main/kotlin/pl/treksoft/kvision/tabulator/TabulatorRemote.kt +++ b/kvision-modules/kvision-tabulator-remote/src/main/kotlin/pl/treksoft/kvision/tabulator/TabulatorRemote.kt @@ -34,6 +34,7 @@ import pl.treksoft.kvision.remote.RemoteFilter import pl.treksoft.kvision.remote.RemoteSorter import pl.treksoft.kvision.table.TableType import pl.treksoft.kvision.utils.JSON +import pl.treksoft.kvision.utils.set import kotlin.browser.window /** @@ -114,10 +115,12 @@ fun Container.tabulatorRemote( stateFunction: (() -> String)? = null, options: TabulatorOptions = TabulatorOptions(), types: Set = setOf(), - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (TabulatorRemote.() -> Unit)? = null ): TabulatorRemote { - val tabulatorRemote = TabulatorRemote(serviceManager, function, stateFunction, options, types, classes) + val tabulatorRemote = + TabulatorRemote(serviceManager, function, stateFunction, options, types, classes ?: className.set) init?.invoke(tabulatorRemote) this.add(tabulatorRemote) return tabulatorRemote diff --git a/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Tabulator.kt b/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Tabulator.kt index 0292a0a4..d830f8a2 100644 --- a/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Tabulator.kt +++ b/kvision-modules/kvision-tabulator/src/main/kotlin/pl/treksoft/kvision/tabulator/Tabulator.kt @@ -33,6 +33,7 @@ import pl.treksoft.kvision.state.ObservableState import pl.treksoft.kvision.table.TableType import pl.treksoft.kvision.utils.createInstance import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set import pl.treksoft.kvision.utils.syncWithList import kotlin.browser.window import pl.treksoft.kvision.tabulator.js.Tabulator as JsTabulator @@ -739,10 +740,11 @@ fun Container.tabulator( dataUpdateOnEdit: Boolean = true, options: TabulatorOptions = TabulatorOptions(), types: Set = setOf(), - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Tabulator.() -> Unit)? = null ): Tabulator { - val tabulator = Tabulator.create(data, dataUpdateOnEdit, options, types, classes) + val tabulator = Tabulator.create(data, dataUpdateOnEdit, options, types, classes ?: className.set) init?.invoke(tabulator) this.add(tabulator) return tabulator @@ -756,10 +758,11 @@ fun Container.tabulator( dataFactory: (S) -> List, options: TabulatorOptions = TabulatorOptions(), types: Set = setOf(), - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Tabulator.() -> Unit)? = null ): Tabulator { - val tabulator = Tabulator.create(store, dataFactory, options, types, classes) + val tabulator = Tabulator.create(store, dataFactory, options, types, classes ?: className.set) init?.invoke(tabulator) this.add(tabulator) return tabulator @@ -771,10 +774,12 @@ fun Container.tabulator( fun Container.tabulator( options: TabulatorOptions = TabulatorOptions(), types: Set = setOf(), - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Tabulator.() -> Unit)? = null ): Tabulator { - val tabulator = Tabulator(dataUpdateOnEdit = false, options = options, types = types, classes = classes) + val tabulator = + Tabulator(dataUpdateOnEdit = false, options = options, types = types, classes = classes ?: className.set) init?.invoke(tabulator) this.add(tabulator) return tabulator diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index 2d2fac29..d077415e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -38,6 +38,7 @@ import pl.treksoft.kvision.utils.SnOn import pl.treksoft.kvision.utils.emptyOn import pl.treksoft.kvision.utils.hooks import pl.treksoft.kvision.utils.on +import pl.treksoft.kvision.utils.set import pl.treksoft.kvision.utils.snAttrs import pl.treksoft.kvision.utils.snClasses import pl.treksoft.kvision.utils.snOpt @@ -121,10 +122,12 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component * A function called after the widget is inserted to the DOM. */ var afterInsertHook: ((VNode) -> Unit)? = null + /** * A function called after the widget is removed from the DOM. */ var afterDestroyHook: (() -> Unit)? = null + /** * A function called after the widget is disposed. */ @@ -756,13 +759,26 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component */ protected open fun createLabelWithIcon( label: String, icon: String? = null, - image: ResString? = null + image: ResString? = null, + separator: String? = null ): Array { val translatedLabel = translate(label) return if (icon != null) { - arrayOf(KVManager.virtualize(""), " $translatedLabel") + if (separator == null) { + arrayOf(KVManager.virtualize(""), " $translatedLabel") + } else { + arrayOf(KVManager.virtualize(""), KVManager.virtualize(separator), translatedLabel) + } } else if (image != null) { - arrayOf(KVManager.virtualize(""), " $translatedLabel") + if (separator == null) { + arrayOf(KVManager.virtualize(""), " $translatedLabel") + } else { + arrayOf( + KVManager.virtualize(""), + KVManager.virtualize(separator), + translatedLabel + ) + } } else { arrayOf(translatedLabel) } @@ -842,8 +858,12 @@ open class Widget(classes: Set = setOf()) : StyledComponent(), Component * * It takes the same parameters as the constructor of the built component. */ -fun Container.widget(classes: Set = setOf(), init: (Widget.() -> Unit)? = null): Widget { - val widget = Widget(classes).apply { init?.invoke(this) } +fun Container.widget( + classes: Set? = null, + className: String? = null, + init: (Widget.() -> Unit)? = null +): Widget { + val widget = Widget(classes ?: className.set).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 index 1d5ada90..aec7c7ab 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/WidgetWrapper.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/WidgetWrapper.kt @@ -23,6 +23,7 @@ package pl.treksoft.kvision.core import com.github.snabbdom.VNode import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.set /** * This class allows to wrap a component into separately styled DIV element. @@ -63,10 +64,11 @@ open class WidgetWrapper(internal var wrapped: Component?, classes: Set */ fun Container.widgetWrapper( wrapped: Component?, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (WidgetWrapper.() -> Unit)? = null ): WidgetWrapper { - val widgetWrapper = WidgetWrapper(wrapped, classes).apply { init?.invoke(this) } + val widgetWrapper = WidgetWrapper(wrapped, classes ?: className.set).apply { init?.invoke(this) } this.add(widgetWrapper) return widgetWrapper } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FieldLabel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FieldLabel.kt index 8413eb3c..e9be793c 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/FieldLabel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/FieldLabel.kt @@ -25,6 +25,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.utils.set /** * Helper class for HTML label element. @@ -37,7 +38,7 @@ import pl.treksoft.kvision.html.Tag */ open class FieldLabel( internal val forId: String, content: String? = null, rich: Boolean = false, - classes: Set = setOf("control-label") + classes: Set = setOf() ) : Tag( TAG.LABEL, content, rich, classes = classes @@ -55,9 +56,11 @@ open class FieldLabel( */ fun Container.fieldLabel( forId: String, content: String? = null, rich: Boolean = false, - classes: Set = setOf("control-label"), init: (FieldLabel.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (FieldLabel.() -> Unit)? = null ): FieldLabel { - val fieldLabel = FieldLabel(forId, content, rich, classes).apply { init?.invoke(this) } + val fieldLabel = FieldLabel(forId, content, rich, classes ?: className.set).apply { init?.invoke(this) } this.add(fieldLabel) return fieldLabel } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt index 8f918a97..7353179a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt @@ -33,6 +33,7 @@ import pl.treksoft.kvision.html.Div import pl.treksoft.kvision.panel.FieldsetPanel import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.types.KFile +import pl.treksoft.kvision.utils.set import kotlin.js.Date import kotlin.js.Json import kotlin.reflect.KClass @@ -504,11 +505,13 @@ open class FormPanel( inline fun Container.formPanel( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, type: FormType? = null, condensed: Boolean = false, - horizRatio: FormHorizontalRatio = FormHorizontalRatio.RATIO_2, classes: Set = setOf(), + horizRatio: FormHorizontalRatio = FormHorizontalRatio.RATIO_2, + classes: Set? = null, className: String? = null, customSerializers: Map, KSerializer<*>>? = null, noinline init: (FormPanel.() -> Unit)? = null ): FormPanel { - val formPanel = create(method, action, enctype, type, condensed, horizRatio, classes, customSerializers) + val formPanel = + create(method, action, enctype, type, condensed, horizRatio, classes ?: className.set, customSerializers) init?.invoke(formPanel) this.add(formPanel) return formPanel diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBoxInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBoxInput.kt index ea8bf7db..5b91d635 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBoxInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBoxInput.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.form.check import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * The basic input component rendered as HTML *input type="checkbox"*. @@ -42,9 +43,11 @@ open class CheckBoxInput( */ fun Container.checkBoxInput( value: Boolean = false, - classes: Set = setOf(), init: (CheckInput.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (CheckInput.() -> Unit)? = null ): CheckBoxInput { - val checkBoxInput = CheckBoxInput(value, classes).apply { init?.invoke(this) } + val checkBoxInput = CheckBoxInput(value, classes ?: className.set).apply { init?.invoke(this) } this.add(checkBoxInput) return checkBoxInput } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt index b162abc8..234f5327 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt @@ -117,7 +117,7 @@ open class RadioGroup( private val idc = "kv_form_radiogroup_$counter" final override val input = RadioInput() - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, setOf("control-label")) final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } internal val container = SimplePanel(setOf("kv-radiogroup-container")) diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioInput.kt index 72bb4cd0..1f8a3b9d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioInput.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.form.check import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * The basic input component rendered as HTML *input type="radio"*. @@ -42,9 +43,11 @@ open class RadioInput( */ fun Container.radioInput( value: Boolean = false, - classes: Set = setOf(), init: (CheckInput.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (CheckInput.() -> Unit)? = null ): RadioInput { - val checkBoxInput = RadioInput(value, classes).apply { init?.invoke(this) } + val checkBoxInput = RadioInput(value, classes ?: className.set).apply { init?.invoke(this) } this.add(checkBoxInput) return checkBoxInput } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/range/Range.kt b/src/main/kotlin/pl/treksoft/kvision/form/range/Range.kt index a54ccddb..dc8e57a0 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/range/Range.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/range/Range.kt @@ -140,7 +140,7 @@ open class Range( this.id = idc this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, setOf("control-label")) final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/range/RangeInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/range/RangeInput.kt index dc9ad7d4..4649c654 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/range/RangeInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/range/RangeInput.kt @@ -30,6 +30,7 @@ import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.FormInput import pl.treksoft.kvision.form.InputSize import pl.treksoft.kvision.form.ValidationStatus +import pl.treksoft.kvision.utils.set internal const val DEFAULT_STEP = 1 @@ -52,6 +53,7 @@ open class RangeInput( * Range input value. */ var value by refreshOnUpdate(value ?: (min as Number?)) { refreshState() } + /** * The value attribute of the generated HTML input element. * @@ -59,38 +61,47 @@ open class RangeInput( * bound to the range input value. */ var startValue by refreshOnUpdate(value) { this.value = it; refresh() } + /** * Minimal value. */ var min by refreshOnUpdate(min) + /** * Maximal value. */ var max by refreshOnUpdate(max) + /** * Step value. */ var step by refreshOnUpdate(step) + /** * The name attribute of the generated HTML input element. */ override var name: String? by refreshOnUpdate() + /** * Determines if the field is disabled. */ override var disabled by refreshOnUpdate(false) + /** * Determines if the range input is automatically focused. */ var autofocus: Boolean? by refreshOnUpdate() + /** * Determines if the range input is read-only. */ var readonly: Boolean? by refreshOnUpdate() + /** * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** * The validation status of the input. */ @@ -221,9 +232,11 @@ open class RangeInput( */ fun Container.rangeInput( value: Number? = null, min: Number = 0, max: Number = 100, step: Number = DEFAULT_STEP, - classes: Set = setOf(), init: (RangeInput.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (RangeInput.() -> Unit)? = null ): RangeInput { - val rangeInput = RangeInput(value, min, max, step, classes).apply { init?.invoke(this) } + val rangeInput = RangeInput(value, min, max, step, classes ?: className.set).apply { init?.invoke(this) } this.add(rangeInput) return rangeInput } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt index 4d47a239..e797e050 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelect.kt @@ -116,7 +116,7 @@ open class SimpleSelect( this.id = idc this.name = name } - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, setOf("control-label")) final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt index bc99f514..63eb98b5 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SimpleSelectInput.kt @@ -31,6 +31,7 @@ import pl.treksoft.kvision.form.ValidationStatus import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.set internal const val KVNULL = "#kvnull" @@ -57,6 +58,7 @@ open class SimpleSelectInput( * Text input value. */ var value by refreshOnUpdate(value) { refreshState() } + /** * The value of the selected child option. * @@ -64,26 +66,32 @@ open class SimpleSelectInput( * bound to the select component. */ var startValue by refreshOnUpdate(value) { this.value = it; selectOption() } + /** * The name attribute of the generated HTML input element. */ override var name: String? by refreshOnUpdate() + /** * Determines if the field is disabled. */ override var disabled by refreshOnUpdate(false) + /** * Determines if the text input is automatically focused. */ var autofocus: Boolean? by refreshOnUpdate() + /** * Determines if an empty option is automatically generated. */ var emptyOption by refreshOnUpdate(emptyOption) { setChildrenFromOptions() } + /** * The size of the input. */ override var size: InputSize? by refreshOnUpdate() + /** * The validation status of the input. */ @@ -208,9 +216,12 @@ open class SimpleSelectInput( */ fun Container.simpleSelectInput( options: List? = null, value: String? = null, emptyOption: Boolean = false, - classes: Set = setOf(), init: (SimpleSelectInput.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (SimpleSelectInput.() -> Unit)? = null ): SimpleSelectInput { - val simpleSelectInput = SimpleSelectInput(options, value, emptyOption, classes).apply { init?.invoke(this) } + val simpleSelectInput = + SimpleSelectInput(options, value, emptyOption, classes ?: className.set).apply { init?.invoke(this) } this.add(simpleSelectInput) return simpleSelectInput } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt index d887e814..8a5acf8b 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractText.kt @@ -113,7 +113,7 @@ abstract class AbstractText(label: String? = null, rich: Boolean = false) : */ protected val idc = "kv_form_text_$counter" abstract override val input: AbstractTextInput - final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val flabel: FieldLabel = FieldLabel(idc, label, rich, setOf("control-label")) final override val invalidFeedback: InvalidFeedback = InvalidFeedback().apply { visible = false } init { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt index acad7853..9503a0b1 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt @@ -24,6 +24,7 @@ package pl.treksoft.kvision.form.text import com.github.snabbdom.VNode import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.utils.set /** * Basic textarea component. @@ -41,10 +42,12 @@ open class TextAreaInput(cols: Int? = null, rows: Int? = null, value: String? = * 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. */ @@ -77,10 +80,12 @@ open class TextAreaInput(cols: Int? = null, rows: Int? = null, value: String? = * 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 = setOf(), + cols: Int? = null, rows: Int? = null, value: String? = null, + classes: Set? = null, + className: String? = null, init: (TextAreaInput.() -> Unit)? = null ): TextAreaInput { - val textAreaInput = TextAreaInput(cols, rows, value, classes).apply { init?.invoke(this) } + val textAreaInput = TextAreaInput(cols, rows, value, classes ?: className.set).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 index d057dcbd..e50e1b30 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/TextInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/TextInput.kt @@ -24,6 +24,7 @@ package pl.treksoft.kvision.form.text import com.github.snabbdom.VNode import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringPair +import pl.treksoft.kvision.utils.set /** * Text input types. @@ -53,6 +54,7 @@ open class TextInput(type: TextInputType = TextInputType.TEXT, value: String? = * Text input type. */ var type by refreshOnUpdate(type) + /** * Determines if autocomplete is enabled for the input element. */ @@ -85,10 +87,12 @@ open class TextInput(type: TextInputType = TextInputType.TEXT, value: String? = * It takes the same parameters as the constructor of the built component. */ fun Container.textInput( - type: TextInputType = TextInputType.TEXT, value: String? = null, classes: Set = setOf(), + type: TextInputType = TextInputType.TEXT, value: String? = null, + classes: Set? = null, + className: String? = null, init: (TextInput.() -> Unit)? = null ): TextInput { - val textInput = TextInput(type, value, classes).apply { init?.invoke(this) } + val textInput = TextInput(type, value, classes ?: className.set).apply { init?.invoke(this) } this.add(textInput) return textInput } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Bold.kt b/src/main/kotlin/pl/treksoft/kvision/html/Bold.kt index 10e8e82f..e21b4f85 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Bold.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Bold.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *b*. @@ -57,10 +58,11 @@ fun Container.bold( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Bold.() -> Unit)? = null ): Bold { - val bold = Bold(content, rich, align, classes).apply { init?.invoke(this) } + val bold = Bold(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(bold) return bold } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt index 44a9a8f3..65527f94 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt @@ -28,6 +28,7 @@ import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.utils.set /** * Button styles. @@ -88,30 +89,37 @@ open class Button( * Button label. */ var text by refreshOnUpdate(text) + /** * Button icon. */ var icon by refreshOnUpdate(icon) + /** * Button style. */ var style by refreshOnUpdate(style) + /** * Button types. */ var type by refreshOnUpdate(type) + /** * 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. */ @@ -155,6 +163,7 @@ open class Button( } return this } + /** * Makes the button focused. */ @@ -181,10 +190,11 @@ fun Container.button( style: ButtonStyle = ButtonStyle.PRIMARY, type: ButtonType = ButtonType.BUTTON, disabled: Boolean = false, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Button.() -> Unit)? = null ): Button { - val button = Button(text, icon, style, type, disabled, classes).apply { init?.invoke(this) } + val button = Button(text, icon, style, type, disabled, classes ?: className.set).apply { init?.invoke(this) } this.add(button) return button } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Canvas.kt b/src/main/kotlin/pl/treksoft/kvision/html/Canvas.kt index 840d5dc7..6d3943ca 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Canvas.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Canvas.kt @@ -27,6 +27,7 @@ import org.w3c.dom.HTMLCanvasElement import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.utils.set /** * Canvas component. @@ -43,6 +44,7 @@ open class Canvas( * The width of the canvas. */ var canvasWidth by refreshOnUpdate(canvasWidth) + /** * The height of the canvas. */ @@ -84,11 +86,13 @@ open class Canvas( * It takes the same parameters as the constructor of the built component. */ fun Container.canvas( - canvasWidth: Int? = null, canvasHeight: Int? = null, classes: Set = setOf(), + canvasWidth: Int? = null, canvasHeight: Int? = null, + classes: Set? = null, + className: String? = null, init: (Canvas.() -> Unit)? = null ): Canvas { val canvas = - Canvas(canvasWidth, canvasHeight, classes).apply { init?.invoke(this) } + Canvas(canvasWidth, canvasHeight, classes ?: className.set).apply { init?.invoke(this) } this.add(canvas) return canvas } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/CustomTag.kt b/src/main/kotlin/pl/treksoft/kvision/html/CustomTag.kt index 34910205..f922d0e0 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/CustomTag.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/CustomTag.kt @@ -23,6 +23,7 @@ package pl.treksoft.kvision.html import com.github.snabbdom.VNode import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * HTML custom tag component. @@ -71,11 +72,13 @@ fun Container.customTag( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, attributes: Map = mapOf(), init: (CustomTag.() -> Unit)? = null ): CustomTag { - val customTag = CustomTag(elementName, content, rich, align, classes, attributes).apply { init?.invoke(this) } + val customTag = + CustomTag(elementName, content, rich, align, classes ?: className.set, attributes).apply { init?.invoke(this) } this.add(customTag) return customTag } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Div.kt b/src/main/kotlin/pl/treksoft/kvision/html/Div.kt index 2ffabe49..e43043e4 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Div.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Div.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *div*. @@ -57,10 +58,11 @@ fun Container.div( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Div.() -> Unit)? = null ): Div { - val div = Div(content, rich, align, classes).apply { init?.invoke(this) } + val div = Div(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(div) return div } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Footer.kt b/src/main/kotlin/pl/treksoft/kvision/html/Footer.kt index c71e346f..87e6e43a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Footer.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Footer.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *footer*. @@ -57,10 +58,11 @@ fun Container.footer( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Footer.() -> Unit)? = null ): Footer { - val footer = Footer(content, rich, align, classes).apply { init?.invoke(this) } + val footer = Footer(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(footer) return footer } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/H1.kt b/src/main/kotlin/pl/treksoft/kvision/html/H1.kt index 6a3ac9cc..dbffb628 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/H1.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/H1.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *h1*. @@ -57,10 +58,11 @@ fun Container.h1( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (H1.() -> Unit)? = null ): H1 { - val h1 = H1(content, rich, align, classes).apply { init?.invoke(this) } + val h1 = H1(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(h1) return h1 } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/H2.kt b/src/main/kotlin/pl/treksoft/kvision/html/H2.kt index 7bdd3473..ad6fd793 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/H2.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/H2.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *h2*. @@ -57,10 +58,11 @@ fun Container.h2( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (H2.() -> Unit)? = null ): H2 { - val h2 = H2(content, rich, align, classes).apply { init?.invoke(this) } + val h2 = H2(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(h2) return h2 } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/H3.kt b/src/main/kotlin/pl/treksoft/kvision/html/H3.kt index 1a2efdbb..c21dcb33 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/H3.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/H3.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *h3*. @@ -57,10 +58,11 @@ fun Container.h3( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (H3.() -> Unit)? = null ): H3 { - val h3 = H3(content, rich, align, classes).apply { init?.invoke(this) } + val h3 = H3(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(h3) return h3 } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/H4.kt b/src/main/kotlin/pl/treksoft/kvision/html/H4.kt index ae00b8a7..903c53ae 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/H4.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/H4.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *h4*. @@ -57,10 +58,11 @@ fun Container.h4( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (H4.() -> Unit)? = null ): H4 { - val h4 = H4(content, rich, align, classes).apply { init?.invoke(this) } + val h4 = H4(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(h4) return h4 } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/H5.kt b/src/main/kotlin/pl/treksoft/kvision/html/H5.kt index c40a0658..f7f268d3 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/H5.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/H5.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *h5*. @@ -57,10 +58,11 @@ fun Container.h5( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (H5.() -> Unit)? = null ): H5 { - val h5 = H5(content, rich, align, classes).apply { init?.invoke(this) } + val h5 = H5(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(h5) return h5 } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/H6.kt b/src/main/kotlin/pl/treksoft/kvision/html/H6.kt index 048ab5df..1d9d3429 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/H6.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/H6.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *h6*. @@ -57,10 +58,11 @@ fun Container.h6( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (H6.() -> Unit)? = null ): H6 { - val h6 = H6(content, rich, align, classes).apply { init?.invoke(this) } + val h6 = H6(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(h6) return h6 } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Header.kt b/src/main/kotlin/pl/treksoft/kvision/html/Header.kt index e62e884e..4f71a669 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Header.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Header.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *header*. @@ -57,10 +58,11 @@ fun Container.header( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Header.() -> Unit)? = null ): Header { - val header = Header(content, rich, align, classes).apply { init?.invoke(this) } + val header = Header(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(header) return header } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Iframe.kt b/src/main/kotlin/pl/treksoft/kvision/html/Iframe.kt index dad33ed4..f164f87d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Iframe.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Iframe.kt @@ -26,6 +26,7 @@ import org.w3c.dom.Window import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.utils.set /** * Iframe sandbox options. @@ -59,26 +60,32 @@ open class Iframe( * The iframe document address. */ var src by refreshOnUpdate(src) + /** * The HTML content of the iframe. */ var srcdoc by refreshOnUpdate(srcdoc) + /** * The name of the iframe. */ var name by refreshOnUpdate(name) + /** * The width of the iframe. */ var iframeWidth by refreshOnUpdate(iframeWidth) + /** * The height of the iframe. */ var iframeHeight by refreshOnUpdate(iframeHeight) + /** * A set of Sandbox options. */ var sandbox by refreshOnUpdate(sandbox) + /** * A current location URL of the iframe. */ @@ -141,11 +148,17 @@ open class Iframe( */ fun Container.iframe( src: String? = null, srcdoc: String? = null, name: String? = null, iframeWidth: Int? = null, - iframeHeight: Int? = null, sandbox: Set? = null, classes: Set = setOf(), + iframeHeight: Int? = null, sandbox: Set? = null, + classes: Set? = null, + className: String? = null, init: (Iframe.() -> Unit)? = null ): Iframe { val iframe = - Iframe(src, srcdoc, name, iframeWidth, iframeHeight, sandbox, classes).apply { init?.invoke(this) } + Iframe(src, srcdoc, name, iframeWidth, iframeHeight, sandbox, classes ?: className.set).apply { + init?.invoke( + this + ) + } this.add(iframe) return iframe } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt index 6496b042..f21d515f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.utils.set /** * Image shapes. @@ -56,18 +57,22 @@ open class Image( * 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. */ @@ -108,9 +113,12 @@ open class Image( */ fun Container.image( src: ResString, alt: String? = null, responsive: Boolean = false, shape: ImageShape? = null, - centered: Boolean = false, classes: Set = setOf(), init: (Image.() -> Unit)? = null + centered: Boolean = false, + classes: Set? = null, + className: String? = null, + init: (Image.() -> Unit)? = null ): Image { - val image = Image(src, alt, responsive, shape, centered, classes).apply { init?.invoke(this) } + val image = Image(src, alt, responsive, shape, centered, classes ?: className.set).apply { init?.invoke(this) } this.add(image) return image } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Li.kt b/src/main/kotlin/pl/treksoft/kvision/html/Li.kt index 75157d60..d9886acd 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Li.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Li.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *li*. @@ -57,10 +58,11 @@ fun Container.li( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Li.() -> Unit)? = null ): Li { - val li = Li(content, rich, align, classes).apply { init?.invoke(this) } + val li = Li(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(li) return li } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt index 2c2f1723..819a8aae 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.set /** * Link component. @@ -36,32 +37,52 @@ import pl.treksoft.kvision.panel.SimplePanel * @param url link URL address * @param icon link icon * @param image link image + * @param separator a separator between label and icon/image (defaults to space) + * @param labelFirst determines if the label is put before children elements (defaults to true) * @param classes a set of CSS class names */ open class Link( label: String, url: String? = null, icon: String? = null, image: ResString? = null, + separator: String? = null, labelFirst: Boolean = true, classes: Set = 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) + /** + * A separator between label and icon/image. + */ + var separator by refreshOnUpdate(separator) + + /** + * Determines if the label is put before children elements. + */ + var labelFirst by refreshOnUpdate(labelFirst) + override fun render(): VNode { - val t = createLabelWithIcon(label, icon, image) - return render("a", t + childrenVNodes()) + val t = createLabelWithIcon(label, icon, image, separator) + return if (labelFirst) { + render("a", t + childrenVNodes()) + } else { + render("a", childrenVNodes() + t) + } } override fun getSnAttrs(): List { @@ -92,9 +113,13 @@ open class Link( */ fun Container.link( label: String, url: String? = null, icon: String? = null, image: ResString? = null, - classes: Set = setOf(), init: (Link.() -> Unit)? = null + separator: String? = null, labelFirst: Boolean = true, + classes: Set? = null, + className: String? = null, + init: (Link.() -> Unit)? = null ): Link { - val link = Link(label, url, icon, image, classes).apply { init?.invoke(this) } + val link = + Link(label, url, icon, image, separator, labelFirst, classes ?: className.set).apply { init?.invoke(this) } this.add(link) return link } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/ListTag.kt b/src/main/kotlin/pl/treksoft/kvision/html/ListTag.kt index cdd18cfc..7484a667 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/ListTag.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/ListTag.kt @@ -28,6 +28,7 @@ import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.set import pl.treksoft.kvision.utils.snClasses import pl.treksoft.kvision.utils.snOpt @@ -64,10 +65,12 @@ open class ListTag( * List type. */ var type by refreshOnUpdate(type) + /** * List of elements. */ var elements by refreshOnUpdate(elements) + /** * Determines if [elements] can contain HTML code. */ @@ -158,9 +161,11 @@ open class ListTag( */ fun Container.listTag( type: ListType, elements: List? = null, rich: Boolean = false, - classes: Set = setOf(), init: (ListTag.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (ListTag.() -> Unit)? = null ): ListTag { - val listTag = ListTag(type, elements, rich, classes, init) + val listTag = ListTag(type, elements, rich, classes ?: className.set, init) this.add(listTag) return listTag } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Main.kt b/src/main/kotlin/pl/treksoft/kvision/html/Main.kt index 631e58a9..54c214b0 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Main.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Main.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *main*. @@ -57,10 +58,11 @@ fun Container.main( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Main.() -> Unit)? = null ): Main { - val main = Main(content, rich, align, classes).apply { init?.invoke(this) } + val main = Main(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(main) return main } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Nav.kt b/src/main/kotlin/pl/treksoft/kvision/html/Nav.kt index 31addd95..5a774cf8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Nav.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Nav.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *nav*. @@ -57,10 +58,11 @@ fun Container.nav( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Nav.() -> Unit)? = null ): Nav { - val nav = Nav(content, rich, align, classes).apply { init?.invoke(this) } + val nav = Nav(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(nav) return nav } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Ol.kt b/src/main/kotlin/pl/treksoft/kvision/html/Ol.kt index 79aa93fb..76370d08 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Ol.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Ol.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *ol*. @@ -51,9 +52,11 @@ open class Ol( */ fun Container.ol( elements: List? = null, rich: Boolean = false, - classes: Set = setOf(), init: (Ol.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Ol.() -> Unit)? = null ): Ol { - val ol = Ol(elements, rich, classes).apply { init?.invoke(this) } + val ol = Ol(elements, rich, classes ?: className.set).apply { init?.invoke(this) } this.add(ol) return ol } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/P.kt b/src/main/kotlin/pl/treksoft/kvision/html/P.kt index d5bb2c4d..c6daaa98 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/P.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/P.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *p*. @@ -57,10 +58,11 @@ fun Container.p( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (P.() -> Unit)? = null ): P { - val p = P(content, rich, align, classes).apply { init?.invoke(this) } + val p = P(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(p) return p } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Section.kt b/src/main/kotlin/pl/treksoft/kvision/html/Section.kt index 43dd8fcf..b880e2fe 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Section.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Section.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *section*. @@ -57,10 +58,11 @@ fun Container.section( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Section.() -> Unit)? = null ): Section { - val section = Section(content, rich, align, classes).apply { init?.invoke(this) } + val section = Section(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(section) return section } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Span.kt b/src/main/kotlin/pl/treksoft/kvision/html/Span.kt index 862d0b2f..c762824f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Span.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Span.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *span*. @@ -57,10 +58,11 @@ fun Container.span( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (Span.() -> Unit)? = null ): Span { - val span = Span(content, rich, align, classes).apply { init?.invoke(this) } + val span = Span(content, rich, align, classes ?: className.set).apply { init?.invoke(this) } this.add(span) return span } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt index 95445ece..f133401d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringBoolPair import pl.treksoft.kvision.i18n.I18n import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.utils.set /** * HTML tags. @@ -131,27 +132,33 @@ open class Tag( * Tag type. */ var type by refreshOnUpdate(type) + /** * Text content of the tag. */ override var content by refreshOnUpdate(content) + /** * Determines if [content] can contain HTML code. */ override var rich by refreshOnUpdate(rich) + /** * Text align. */ var align by refreshOnUpdate(align) + /** * @suppress * Internal property */ override var templateDataObj: Any? = null + /** * Handlebars template. */ override var template: ((Any?) -> String)? by refreshOnUpdate() + /** * Handlebars templates for i18n. */ @@ -207,10 +214,12 @@ open class Tag( */ fun Container.tag( type: TAG, content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), attributes: Map = mapOf(), + classes: Set? = null, + className: String? = null, + attributes: Map = mapOf(), init: (Tag.() -> Unit)? = null ): Tag { - val tag = Tag(type, content, rich, align, classes, attributes, init) + val tag = Tag(type, content, rich, align, classes ?: className.set, attributes, init) this.add(tag) return tag } diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Ul.kt b/src/main/kotlin/pl/treksoft/kvision/html/Ul.kt index 9673f56d..21e548c8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Ul.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Ul.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.html import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * Simple component rendered as *ul*. @@ -51,9 +52,11 @@ open class Ul( */ fun Container.ul( elements: List? = null, rich: Boolean = false, - classes: Set = setOf(), init: (Ul.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Ul.() -> Unit)? = null ): Ul { - val ul = Ul(elements, rich, classes).apply { init?.invoke(this) } + val ul = Ul(elements, rich, classes ?: className.set).apply { init?.invoke(this) } this.add(ul) return ul } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt index 59c61637..52239032 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt @@ -24,6 +24,7 @@ package pl.treksoft.kvision.panel import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.utils.perc +import pl.treksoft.kvision.utils.set /** * Dock layout directions. @@ -50,21 +51,25 @@ open class DockPanel(classes: Set = setOf(), init: (DockPanel.() -> Unit * 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. @@ -83,6 +88,7 @@ open class DockPanel(classes: Set = setOf(), init: (DockPanel.() -> Unit @Suppress("MagicNumber") height = 100.perc } + /** * @suppress * Internal property. @@ -204,8 +210,12 @@ open class DockPanel(classes: Set = setOf(), init: (DockPanel.() -> Unit * * It takes the same parameters as the constructor of the built component. */ -fun Container.dockPanel(classes: Set = setOf(), init: (DockPanel.() -> Unit)? = null): DockPanel { - val dockPanel = DockPanel(classes, init) +fun Container.dockPanel( + classes: Set? = null, + className: String? = null, + init: (DockPanel.() -> Unit)? = null +): DockPanel { + val dockPanel = DockPanel(classes ?: className.set, init) this.add(dockPanel) return dockPanel } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/FieldsetPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/FieldsetPanel.kt index 14310ffc..b6998556 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/FieldsetPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/FieldsetPanel.kt @@ -25,6 +25,7 @@ import com.github.snabbdom.VNode import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.utils.set /** * The HTML fieldset container. @@ -74,10 +75,11 @@ open class FieldsetPanel( */ fun Container.fieldsetPanel( legend: String? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (FieldsetPanel.() -> Unit)? = null ): FieldsetPanel { - val fieldsetPanel = FieldsetPanel(legend, classes, init) + val fieldsetPanel = FieldsetPanel(legend, classes ?: className.set, init) this.add(fieldsetPanel) return fieldsetPanel } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt index 4cdbfa01..13deaeb0 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt @@ -27,6 +27,7 @@ import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.core.WidgetWrapper import pl.treksoft.kvision.utils.px +import pl.treksoft.kvision.utils.set /** * CSS flexbox directions. @@ -237,9 +238,13 @@ open class FlexPanel( fun Container.flexPanel( direction: FlexDir? = null, wrap: FlexWrap? = null, justify: FlexJustify? = null, alignItems: FlexAlignItems? = null, alignContent: FlexAlignContent? = null, - spacing: Int? = null, classes: Set = setOf(), init: (FlexPanel.() -> Unit)? = null + spacing: Int? = null, + classes: Set? = null, + className: String? = null, + init: (FlexPanel.() -> Unit)? = null ): FlexPanel { - val flexPanel = FlexPanel(direction, wrap, justify, alignItems, alignContent, spacing, classes, init) + val flexPanel = + FlexPanel(direction, wrap, justify, alignItems, alignContent, spacing, classes ?: className.set, init) this.add(flexPanel) return flexPanel } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt index 1598753b..daf5c92b 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt @@ -25,6 +25,7 @@ import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.StringPair import pl.treksoft.kvision.core.WidgetWrapper +import pl.treksoft.kvision.utils.set /** * CSS grid justification options. @@ -113,46 +114,57 @@ open class GridPanel( * 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. */ @@ -267,11 +279,14 @@ fun Container.gridPanel( templateColumns: String? = null, templateRows: String? = null, templateAreas: List? = null, columnGap: Int? = null, rowGap: Int? = null, justifyItems: GridJustify? = null, alignItems: GridAlign? = null, justifyContent: GridJustifyContent? = null, - alignContent: GridAlignContent? = null, classes: Set = setOf(), init: (GridPanel.() -> Unit)? = null + alignContent: GridAlignContent? = null, + classes: Set? = null, + className: String? = null, + init: (GridPanel.() -> Unit)? = null ): GridPanel { val gridPanel = GridPanel( autoColumns, autoRows, autoFlow, templateColumns, templateRows, templateAreas, - columnGap, rowGap, justifyItems, alignItems, justifyContent, alignContent, classes, init + columnGap, rowGap, justifyItems, alignItems, justifyContent, alignContent, classes ?: className.set, init ) this.add(gridPanel) return gridPanel diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt index ccc77b0f..88c95b92 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.panel import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * The container with horizontal layout. @@ -59,10 +60,11 @@ fun Container.hPanel( justify: FlexJustify? = null, alignItems: FlexAlignItems? = null, spacing: Int? = null, - classes: Set = setOf(), + classes: Set? = null, + className: String? = null, init: (HPanel.() -> Unit)? = null ): HPanel { - val hpanel = HPanel(wrap, justify, alignItems, spacing, classes, init) + val hpanel = HPanel(wrap, justify, alignItems, spacing, classes ?: className.set, init) this.add(hpanel) return hpanel } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt index 915fa6a7..f2210550 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt @@ -25,6 +25,7 @@ import com.github.snabbdom.VNode import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.utils.set /** * Basic container class, rendered as a DIV element with all children directly within. @@ -108,8 +109,12 @@ open class SimplePanel(classes: Set = setOf(), init: (SimplePanel.() -> * * It takes the same parameters as the constructor of the built component. */ -fun Container.simplePanel(classes: Set = setOf(), init: (SimplePanel.() -> Unit)? = null): SimplePanel { - val simplePanel = SimplePanel(classes, init) +fun Container.simplePanel( + classes: Set? = null, + className: String? = null, + init: (SimplePanel.() -> Unit)? = null +): SimplePanel { + val simplePanel = SimplePanel(classes ?: className.set, 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 index c7f4b3ac..f838e85c 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/SplitPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/SplitPanel.kt @@ -30,6 +30,7 @@ import pl.treksoft.kvision.core.UNIT import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.utils.obj +import pl.treksoft.kvision.utils.set /** * Split panel direction. @@ -107,9 +108,11 @@ open class SplitPanel( */ fun Container.splitPanel( direction: Direction = Direction.VERTICAL, - classes: Set = setOf(), init: (SplitPanel.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (SplitPanel.() -> Unit)? = null ): SplitPanel { - val splitPanel = SplitPanel(direction, classes, init) + val splitPanel = SplitPanel(direction, classes ?: className.set, init) this.add(splitPanel) return splitPanel } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt index 84fb6174..02a77b55 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt @@ -25,6 +25,7 @@ import com.github.snabbdom.VNode import pl.treksoft.kvision.core.Component import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.routing.routing +import pl.treksoft.kvision.utils.set import kotlin.browser.window /** @@ -130,9 +131,12 @@ open class StackPanel( * It takes the same parameters as the constructor of the built component. */ fun Container.stackPanel( - activateLast: Boolean = true, classes: Set = setOf(), init: (StackPanel.() -> Unit)? = null + activateLast: Boolean = true, + classes: Set? = null, + className: String? = null, + init: (StackPanel.() -> Unit)? = null ): StackPanel { - val stackPanel = StackPanel(activateLast, classes, init) + val stackPanel = StackPanel(activateLast, classes ?: className.set, init) this.add(stackPanel) return stackPanel } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt index e5d275d4..42471994 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.panel import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.utils.set /** * The container with vertical layout. @@ -55,9 +56,11 @@ open class VPanel( */ fun Container.vPanel( justify: FlexJustify? = null, alignItems: FlexAlignItems? = null, spacing: Int? = null, - classes: Set = setOf(), init: (VPanel.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (VPanel.() -> Unit)? = null ): VPanel { - val vpanel = VPanel(justify, alignItems, spacing, classes, init) + val vpanel = VPanel(justify, alignItems, spacing, classes ?: className.set, init) this.add(vpanel) return vpanel } diff --git a/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt b/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt index 4cf72f77..467f1d1d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/Cell.kt @@ -24,6 +24,7 @@ package pl.treksoft.kvision.table import pl.treksoft.kvision.html.Align import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.utils.set /** * HTML table cell component. @@ -58,9 +59,11 @@ fun Row.cell( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), init: (Cell.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Cell.() -> Unit)? = null ): Cell { - val cell = Cell(content, rich, align, classes, init) + val cell = Cell(content, rich, align, classes ?: className.set, init) this.add(cell) return cell } @@ -74,9 +77,11 @@ fun Row.thcell( content: String? = null, rich: Boolean = false, align: Align? = null, - classes: Set = setOf(), init: (HeaderCell.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (HeaderCell.() -> Unit)? = null ): HeaderCell { - val headerCell = HeaderCell(content, rich, align, Scope.ROW, classes, init) + val headerCell = HeaderCell(content, rich, align, Scope.ROW, classes ?: className.set, init) this.add(headerCell) return headerCell } diff --git a/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt b/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt index f7f45784..626ab87f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/HeaderCell.kt @@ -24,6 +24,7 @@ package pl.treksoft.kvision.table import pl.treksoft.kvision.html.Align import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.utils.set enum class Scope(internal val scope: String) { ROW("row"), @@ -69,9 +70,11 @@ fun Row.headerCell( rich: Boolean = false, align: Align? = null, scope: Scope? = null, - classes: Set = setOf(), init: (HeaderCell.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (HeaderCell.() -> Unit)? = null ): HeaderCell { - val cell = HeaderCell(content, rich, align, scope, classes, init) + val cell = HeaderCell(content, rich, align, scope, classes ?: className.set, 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 index 0681953f..a933d38e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/Row.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/Row.kt @@ -23,6 +23,7 @@ package pl.treksoft.kvision.table import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.utils.set /** * HTML table row component. @@ -46,9 +47,11 @@ open class Row(classes: Set = setOf(), init: (Row.() -> Unit)? = null) : * It takes the same parameters as the constructor of the built component. */ fun Table.row( - classes: Set = setOf(), init: (Row.() -> Unit)? = null + classes: Set? = null, + className: String? = null, + init: (Row.() -> Unit)? = null ): Row { - val row = Row(classes, init) + val row = Row(classes ?: className.set, 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 index 6c48157d..56d4a811 100644 --- a/src/main/kotlin/pl/treksoft/kvision/table/Table.kt +++ b/src/main/kotlin/pl/treksoft/kvision/table/Table.kt @@ -29,6 +29,7 @@ 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.set import pl.treksoft.kvision.utils.snClasses import pl.treksoft.kvision.utils.snOpt @@ -85,14 +86,17 @@ open class 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. */ @@ -210,10 +214,13 @@ open class Table( fun Container.table( headerNames: List? = null, types: Set = setOf(), caption: String? = null, responsiveType: ResponsiveType? = null, - theadType: TheadType? = null, classes: Set = setOf(), init: (Table.() -> Unit)? = null + theadType: TheadType? = null, + classes: Set? = null, + className: String? = null, + init: (Table.() -> Unit)? = null ): Table { val table = - Table(headerNames, types, caption, responsiveType, theadType, classes, init) + Table(headerNames, types, caption, responsiveType, theadType, classes ?: className.set, init) this.add(table) return table } diff --git a/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt b/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt index 5f245fb6..e2833630 100644 --- a/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt +++ b/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt @@ -200,3 +200,11 @@ fun MutableList.syncWithList(list: List) { } } } + +/** + * Utility extension property to generate a set of strings to simplify the notation when using classes parameter. + */ +val String?.set: Set + get() { + return this?.split(Regex("\\s+"))?.toSet() ?: setOf() + } diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/FieldLabelSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/FieldLabelSpec.kt index 583fb2a3..a6f8d197 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/FieldLabelSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/FieldLabelSpec.kt @@ -33,7 +33,7 @@ class FieldLabelSpec : DomSpec { fun render() { run { val root = Root("test", containerType = pl.treksoft.kvision.panel.ContainerType.FIXED) - val fl = FieldLabel("input", "Label") + val fl = FieldLabel("input", "Label", classes = setOf("control-label")) root.add(fl) val element = document.getElementById("test") assertEqualsHtml( -- cgit