Compare commits

...

58 Commits

Author SHA1 Message Date
53b020ab8d improve AttrsWithContentBuilder functions 2022-05-19 18:56:52 +06:00
67a6998f02 add new variant of NavbarNav 2022-05-19 18:50:43 +06:00
abe44fe1c6 fixes in signature of NavbarNav fun 2022-05-19 18:50:06 +06:00
b028b12103 small fixes in UIKitNav 2022-05-19 18:47:03 +06:00
816f341729 fixes in UIKitNavbar invoke 2022-05-19 18:44:19 +06:00
6a652249c0 improvements and fixes in Navbar and NavbarNav parts 2022-05-19 18:43:41 +06:00
ec584798ad Update Navbar.kt 2022-05-19 15:23:04 +06:00
faf238cf07 fix in navbar 2022-05-19 14:38:35 +06:00
d78acce3c5 add several builders for AttrsWithContentBuilder 2022-05-19 14:16:30 +06:00
3afe6c2815 add support of sections 2022-05-19 13:42:21 +06:00
29efe4b5cd Improve support of navbars 2022-05-19 13:21:39 +06:00
990bd6385f start 0.1.3 2022-05-19 13:21:29 +06:00
deb30957ac Merge pull request #57 from InsanusMokrassar/0.1.2
0.1.2
2022-05-19 02:13:29 -04:00
276eaddcac Remove redundant DList and other + add AttrsWithContentBuilder 2022-05-19 12:13:13 +06:00
9b992cbda0 start 0.1.2 2022-05-19 12:10:49 +06:00
e227d3c88e Merge pull request #56 from InsanusMokrassar/0.1.1
0.1.1
2022-05-17 02:33:50 -04:00
fc4f937cc1 Update CHANGELOG.md 2022-05-17 12:30:38 +06:00
1ee9b8c4de Update libs.versions.toml 2022-05-17 12:29:51 +06:00
90e27d0cab start 0.1.1 2022-05-17 12:29:18 +06:00
400724c918 Merge pull request #55 from InsanusMokrassar/0.1.0
0.1.0
2022-05-16 00:00:24 +06:00
ea59ba1446 Update CHANGELOG.md 2022-05-15 23:58:58 +06:00
a97898fe69 Update libs.versions.toml 2022-05-15 23:58:00 +06:00
21d2ccf208 Update CHANGELOG.md 2022-05-10 15:05:06 +06:00
fd6a122b40 Update libs.versions.toml 2022-05-10 15:04:54 +06:00
6b4e141cd2 update release version 2022-05-07 01:46:31 +06:00
fb5e0ade11 update compose dependency 2022-05-07 01:43:57 +06:00
353314dd26 add dev compose maven 2022-04-29 17:34:10 +06:00
57ffe32b9f Update of dependencies 2022-04-29 17:29:37 +06:00
c6bacffdb3 start 0.1.0 2022-04-29 17:28:52 +06:00
3e2aa22076 Merge pull request #54 from InsanusMokrassar/0.0.53
0.0.53
2022-04-27 16:29:24 +06:00
5842da03d0 new function ListWithTitle 2022-04-27 16:24:57 +06:00
6daa57fe8f improve support of List 2022-04-27 16:13:58 +06:00
8adbe8a1ca Add support of UIKit lists 2022-04-27 16:07:07 +06:00
468f167ac6 Improvements in UIKitPadding 2022-04-27 15:44:06 +06:00
c41e2b8495 start 0.0.53 2022-04-27 15:43:55 +06:00
7cdd12e81e Merge pull request #53 from InsanusMokrassar/0.0.52
0.0.52
2022-04-26 15:09:19 +06:00
f3ce0f6b6b Improve work with UIKitModifiers 2022-04-26 14:54:26 +06:00
d24edcbaf7 start 0.0.52 2022-04-26 14:54:19 +06:00
fdd98bab13 Merge pull request #52 from InsanusMokrassar/0.0.51
0.0.51
2022-04-15 13:21:20 +06:00
ed6582c98d now it is impossible to pass null in hide fun of dropdown 2022-04-15 13:20:30 +06:00
4b697938ac a little fix in hide of dropdown 2022-04-15 13:12:04 +06:00
ebb350c688 Improvements in Dropdowns and new attribute in NavItemElement 2022-04-15 13:06:14 +06:00
8c2ce7b75d start 0.0.51 2022-04-15 13:05:20 +06:00
2d62f9847a Merge pull request #51 from InsanusMokrassar/0.0.50
0.0.50
2022-04-04 00:57:44 +06:00
3746b614cf rename new property 2022-04-04 00:07:33 +06:00
2ece25ef4e add opportunity to customize default header content of nav 2022-04-03 23:58:08 +06:00
18ffabf76d start 0.0.50 2022-04-03 23:57:39 +06:00
c5ef64ebe4 Merge pull request #50 from InsanusMokrassar/0.0.49
0.0.49
2022-04-03 18:36:34 +06:00
ee1bea8ee1 in navs now titles are optional 2022-04-03 16:03:13 +06:00
4a7b125abe start 0.0.49 2022-04-03 16:02:55 +06:00
a756bab2a6 Merge pull request #49 from InsanusMokrassar/0.0.48
0.0.48
2022-03-31 13:32:41 +06:00
be4d63f0e0 improvements in UIKitModifier tools 2022-03-31 09:12:01 +06:00
b177760c73 add UIKDropdown#Mode for none and hover and click 2022-03-30 21:08:29 +06:00
82f00fa23b All attribute values now will print their name as result of toString 2022-03-30 20:48:38 +06:00
33b1a7af65 fixes in dropdown position 2022-03-30 20:33:19 +06:00
e6b0ca580a support of breadcrumb 2022-03-30 16:41:07 +06:00
d5045bdba7 start 0.0.48 2022-03-30 16:40:51 +06:00
186eff482d Merge pull request #48 from InsanusMokrassar/0.0.47
0.0.47
2022-03-25 21:01:54 +06:00
30 changed files with 656 additions and 146 deletions

View File

@@ -1,5 +1,52 @@
# Changelog
## 0.1.3
* Add support of sections
* Improve support of navbars
## 0.1.2
* New typealias `AttrsWithContentBuilder`
* Old `DList` and related composable functions removed (they are built-in in compose)
## 0.1.1
* `Compose`: `1.2.0-alpha01-dev686`
## 0.1.0
* `Kotlin` = `1.6.21`
* `Compose`: `1.2.0-alpha01-dev683`
## 0.0.53
* Improvements in `UIKitPadding`
* Add support of UIKit lists
## 0.0.52
* Improve work with UIKitModifiers
## 0.0.51
* New interface `Dropdown` which will be used to create (or retrieve) dropdown for an element
* New attribute in `NavItemElement` for configuration of `A` element
## 0.0.50
* Add opportunity to customize content in title of `Nav` after text
## 0.0.49
* Now it is possible to use optional title in navs builders
## 0.0.48
* Added support of `Breadcrumb`
* Add opportunity to summarize `UIKitModifier`
* Add opportunity to simply create attributes builder using `UIKitModifier` of array of them
## 0.0.47
* Add support of `Close` element

View File

@@ -26,6 +26,7 @@ repositories {
mavenLocal()
mavenCentral()
google()
maven { url "https://maven.pkg.jetbrains.space/public/p/compose/dev" }
}
kotlin {

View File

@@ -9,4 +9,4 @@ android.enableJetifier=true
# Project data
group=dev.inmo
version=0.0.47
version=0.1.3

View File

@@ -1,9 +1,9 @@
[versions]
kt = "1.6.10"
jb-compose = "1.1.1"
jb-dokka = "1.6.10"
gh-release = "2.2.12"
kt = "1.6.21"
jb-compose = "1.2.0-alpha01-dev686"
jb-dokka = "1.6.21"
gh-release = "2.3.7"
[libraries]

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -1,8 +1,7 @@
package dev.inmo.jsuikit
import dev.inmo.jsuikit.modifiers.AttributeValue
import dev.inmo.jsuikit.utils.AttributeBuilder
import dev.inmo.jsuikit.utils.buildAttribute
import dev.inmo.jsuikit.utils.*
import org.jetbrains.compose.web.attributes.AttrsScope
@Deprecated("Will be removed soon")
@@ -25,7 +24,7 @@ class UIKitAttributeValueBuilder {
fun AttrsScope<*>.buildAndAddAttribute(
attributeName: String,
skipNullValues: Boolean = true,
block: AttributeBuilder.() -> Unit
block: ParametersBuilder.() -> Unit
) {
buildAttribute(attributeName, skipNullValues, block).let {
attr(it.first, it.second)

View File

@@ -0,0 +1,50 @@
package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.UIKitBreadcrumb
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.*
@Composable
fun <T> Breadcrumb(
data: Iterable<T>,
rootAttrs: Attrs<HTMLUListElement> = Attrs.empty(),
elementAttrs: Attrs<HTMLLIElement> = Attrs.empty(),
elementContent: @Composable ElementScope<HTMLLIElement>.(T) -> Unit = {},
) {
Ul(
{
include(UIKitBreadcrumb)
rootAttrs.builder(this)
}
) {
data.forEach {
Li({ elementAttrs.builder(this) }) {
elementContent(it)
}
}
}
}
@Composable
fun BreadcrumbActiveElement(
href: String? = "#",
elementAttrs: Attrs<HTMLAnchorElement> = Attrs.empty(),
elementContent: @Composable ElementScope<HTMLAnchorElement>.() -> Unit = {},
) {
A(href, { elementAttrs.builder(this) }) {
elementContent()
}
}
@Composable
fun BreadcrumbInactiveElement(
elementAttrs: Attrs<HTMLSpanElement> = Attrs.empty(),
elementContent: @Composable ElementScope<HTMLSpanElement>.() -> Unit = {},
) {
Span({ elementAttrs.builder(this) }) {
elementContent()
}
}

View File

@@ -4,8 +4,7 @@ import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.UIKitDescriptionList
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.utils.*
import org.jetbrains.compose.web.dom.ContentBuilder
import org.jetbrains.compose.web.dom.ElementScope
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLDListElement
import org.w3c.dom.HTMLElement

View File

@@ -10,7 +10,7 @@ import org.w3c.dom.HTMLDivElement
@Composable
fun DropArea(
attrs: Attrs<HTMLDivElement> = Attrs.empty(),
inputAttrs: InputAttrs<String> = Attrs.empty(),
inputAttrs: InputAttrs<String> = InputAttrs.empty(),
contentBuilder: ContentBuilder<HTMLDivElement> = {}
) = Div(
{

View File

@@ -3,10 +3,26 @@ package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.buildAndAddAttribute
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.types.DropdownOptions
import dev.inmo.jsuikit.utils.Milliseconds
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLDivElement
@Composable
fun Dropdown(
vararg modifiers: UIKitModifier,
dropdownOptions: DropdownOptions,
attributesCustomizer: AttrBuilderContext<HTMLDivElement> = {},
contentBuilder: ContentBuilder<HTMLDivElement>
) {
Div(
{
include(UIKitDropdown(dropdownOptions), *modifiers)
attributesCustomizer()
},
contentBuilder
)
}
@Composable
fun Dropdown(
vararg modifiers: UIKitModifier,
@@ -26,21 +42,24 @@ fun Dropdown(
) {
Div(
{
buildAndAddAttribute("uk-dropdown") {
"toggle" to toggle
"pos" to pos
"mode" to mode
"delayShow" to delayShow
"delayHide" to delayHide
"boundary" to boundary
"boundaryAlign" to boundaryAlign
"flip" to flip
"offset" to offset
"animation" to animation
"duration" to duration
}
classes("uk-dropdown")
include(*modifiers)
include(
UIKitDropdown(
DropdownOptions(
toggle = toggle,
pos = pos,
mode = mode,
delayShow = delayShow,
delayHide = delayHide,
boundary = boundary,
boundaryAlign = boundaryAlign,
flip = flip,
offset = offset,
animation = animation,
duration = duration
)
),
*modifiers
)
attributesCustomizer()
},
contentBuilder

View File

@@ -2,14 +2,32 @@ package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import androidx.compose.runtime.snapshots.SnapshotStateList
import dev.inmo.jsuikit.modifiers.UIKitModifier
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLHeadingElement
import org.w3c.dom.HTMLUListElement
@Composable
fun <T> List(
data: SnapshotStateList<T>,
ukAttrs: Attrs<HTMLUListElement> = Attrs.empty(),
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) {
Ul(
{
include(UIKitList)
ukAttrs.builder(this)
}
) {
data.forEach {
elementAllocator(it)
}
}
}
@Composable
fun <T> ListWithTitle(
title: String,
data: SnapshotStateList<T>,
vararg titleModifiers: UIKitModifier,
@@ -23,15 +41,27 @@ fun <T> List(
Text(title)
}
besidesTitleAndList ?.invoke()
Ul(
{
classes("uk-list")
include(*ulModifiers)
ulCustomizer()
}
) {
data.forEach {
elementAllocator(it)
}
}
List(data, Attrs(*ulModifiers) { ulCustomizer(this) }, elementAllocator)
}
@Deprecated("Renamed", ReplaceWith("ListWithTitle", "dev.inmo.jsuikit.elements.ListWithTitle"))
@Composable
fun <T> List(
title: String,
data: SnapshotStateList<T>,
vararg titleModifiers: UIKitModifier,
ulModifiers: Array<UIKitModifier> = emptyArray(),
besidesTitleAndList: (@Composable () -> Unit)? = null,
titleCustomizer: AttrBuilderContext<HTMLHeadingElement> = {},
ulCustomizer: AttrBuilderContext<HTMLUListElement> = {},
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) = ListWithTitle(
title,
data,
*titleModifiers,
ulModifiers = ulModifiers,
besidesTitleAndList = besidesTitleAndList,
titleCustomizer = titleCustomizer,
ulCustomizer = ulCustomizer,
elementAllocator = elementAllocator
)

View File

@@ -1,7 +1,6 @@
package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import androidx.compose.runtime.snapshots.SnapshotStateList
import dev.inmo.jsuikit.buildAndAddAttribute
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.Milliseconds
@@ -94,7 +93,7 @@ fun SubNav(
@Composable
fun <T> Nav(
title: String,
title: String?,
data: Iterable<T>,
vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(),
@@ -104,6 +103,7 @@ fun <T> Nav(
duration: Milliseconds? = null,
besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null,
titleCustomizer: AttrBuilderContext<HTMLLIElement> = {},
afterTitleContentBuilder: ContentBuilder<HTMLLIElement> = {},
ulCustomizer: AttrBuilderContext<HTMLUListElement> = {},
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) {
@@ -119,11 +119,14 @@ fun <T> Nav(
ulCustomizer()
}
) {
NavHeader(
title,
*titleModifiers,
attributesCustomizer = titleCustomizer
)
title ?.let {
NavHeader(
title,
*titleModifiers,
attributesCustomizer = titleCustomizer,
afterTitleContentBuilder = afterTitleContentBuilder
)
}
besidesTitleAndList ?.let { it() }
data.forEach {
elementAllocator(it)
@@ -133,7 +136,7 @@ fun <T> Nav(
@Composable
fun <T> DefaultNav(
title: String,
title: String?,
data: Iterable<T>,
vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(),
@@ -143,6 +146,7 @@ fun <T> DefaultNav(
duration: Milliseconds? = null,
besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null,
titleCustomizer: AttrBuilderContext<HTMLLIElement> = {},
afterTitleContentBuilder: ContentBuilder<HTMLLIElement> = {},
ulCustomizer: AttrBuilderContext<HTMLUListElement> = {},
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) = Nav(
@@ -156,13 +160,14 @@ fun <T> DefaultNav(
duration,
besidesTitleAndList,
titleCustomizer,
afterTitleContentBuilder,
ulCustomizer,
elementAllocator
)
@Composable
fun <T> PrimaryNav(
title: String,
title: String?,
data: Iterable<T>,
vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(),
@@ -172,6 +177,7 @@ fun <T> PrimaryNav(
duration: Milliseconds? = null,
besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null,
titleCustomizer: AttrBuilderContext<HTMLLIElement> = {},
afterTitleContentBuilder: ContentBuilder<HTMLLIElement> = {},
ulCustomizer: AttrBuilderContext<HTMLUListElement> = {},
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) = Nav(
@@ -185,13 +191,14 @@ fun <T> PrimaryNav(
duration,
besidesTitleAndList,
titleCustomizer,
afterTitleContentBuilder,
ulCustomizer,
elementAllocator
)
@Composable
fun <T> SubNav(
title: String,
title: String?,
data: Iterable<T>,
vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(),
@@ -201,6 +208,7 @@ fun <T> SubNav(
duration: Milliseconds? = null,
besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null,
titleCustomizer: AttrBuilderContext<HTMLLIElement> = {},
afterTitleContentBuilder: ContentBuilder<HTMLLIElement> = {},
ulCustomizer: AttrBuilderContext<HTMLUListElement> = {},
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) = Nav(
@@ -214,6 +222,7 @@ fun <T> SubNav(
duration,
besidesTitleAndList,
titleCustomizer,
afterTitleContentBuilder,
ulCustomizer,
elementAllocator
)
@@ -223,6 +232,7 @@ fun NavHeader(
text: String,
vararg modifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLLIElement> = {},
afterTitleContentBuilder: ContentBuilder<HTMLLIElement> = {}
) {
Li(
{
@@ -231,6 +241,7 @@ fun NavHeader(
}
) {
Text(text)
afterTitleContentBuilder()
}
}
@@ -238,6 +249,7 @@ fun NavHeader(
fun NavItemElement(
vararg modifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLLIElement> = {},
anchorAttributesCustomizer: AttrBuilderContext<HTMLAnchorElement> = {},
contentAllocator: ContentBuilder<HTMLAnchorElement>
) {
Li(
@@ -246,7 +258,7 @@ fun NavItemElement(
attributesCustomizer()
}
) {
A("#") {
A("#", attrs = anchorAttributesCustomizer) {
contentAllocator()
}
}

View File

@@ -1,35 +1,76 @@
package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.UIKitModifier
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.*
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLDivElement
import org.w3c.dom.HTMLElement
@Composable
fun Navbar(
leftBuilder: NavbarNavBuilder? = null,
attributesCustomizer: AttrBuilderContext<HTMLElement> = {},
contentBuilder: ContentBuilder<HTMLElement>
) {
Nav(
{
include(UIKitNavbar, UIKitNavbar(), UIKitNavbar.Container)
attributesCustomizer()
}
) {
contentBuilder()
}
}
@Deprecated("Will be removed soon. Use the variant with AttrsWithContentBuilders")
@Composable
fun Navbar(
leftBuilder: NavbarNavBuilder?,
centerBuilder: NavbarNavBuilder? = null,
rightBuilder: NavbarNavBuilder? = null,
vararg navModifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLElement> = {},
) {
Nav(
Navbar(
{
attr("uk-navbar", "")
classes("uk-navbar-container", "uk-navbar")
include(*navModifiers)
attributesCustomizer()
}
) {
leftBuilder ?.let {
Div({ classes("uk-navbar-left") }) { it.draw() }
Div({ include(UIKitNavbar.Alignment.Left) }) { it.draw() }
}
centerBuilder ?.let {
Div({ classes("uk-navbar-center") }) { it.draw() }
Div({ include(UIKitNavbar.Alignment.Center) }) { it.draw() }
}
rightBuilder ?.let {
Div({ classes("uk-navbar-right") }) { it.draw() }
Div({ include(UIKitNavbar.Alignment.Right) }) { it.draw() }
}
}
}
@Composable
fun Navbar(
leftBuilder: AttrsWithContentBuilder<HTMLDivElement>? = null,
centerBuilder: AttrsWithContentBuilder<HTMLDivElement>? = null,
rightBuilder: AttrsWithContentBuilder<HTMLDivElement>? = null,
vararg navModifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLElement> = {},
) {
Navbar(
attributesCustomizer = {
include(*navModifiers)
attributesCustomizer()
}
) {
leftBuilder ?.let {
Div({ include(UIKitNavbar.Alignment.Left);leftBuilder.attributesBuilderContext(this) }, leftBuilder.builder)
}
centerBuilder ?.let {
Div({ include(UIKitNavbar.Alignment.Center);centerBuilder.attributesBuilderContext(this) }, centerBuilder.builder)
}
rightBuilder ?.let {
Div({ include(UIKitNavbar.Alignment.Right);rightBuilder.attributesBuilderContext(this) }, rightBuilder.builder)
}
}
}

View File

@@ -1,13 +1,37 @@
package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.UIKitModifier
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.*
import org.jetbrains.compose.web.attributes.AttrsScope
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLLIElement
import org.w3c.dom.HTMLUListElement
@Composable
fun NavbarNav(
elements: List<AttrsWithContentBuilder<HTMLLIElement>>,
attrs: Attrs<HTMLUListElement> = Attrs.empty()
) {
Ul(
{
include(UIKitNavbar.Nav)
attrs.builder(this)
}
) {
elements.forEach { element ->
Li(element.attributesBuilderContext, element.builder)
}
}
}
@Composable
fun NavbarNav(
vararg elements: AttrsWithContentBuilder<HTMLLIElement>,
attrs: Attrs<HTMLUListElement> = Attrs.empty()
) = NavbarNav(elements.toList(), attrs)
@Deprecated("Will be removed soon. Use NavbarNavPart with AttrsWithContentBuilder instead")
interface NavbarNavElement {
fun AttrsScope<HTMLLIElement>.setup() {}
@Composable
@@ -28,6 +52,7 @@ interface NavbarNavElement {
}
}
@Deprecated("Will be removed soon. Use NavbarNavPart with AttrsWithContentBuilder instead")
class NavbarNavBuilder(
private val modifiers: Array<UIKitModifier>,
private val elements: List<NavbarNavElement>,
@@ -46,8 +71,7 @@ class NavbarNavBuilder(
fun draw() {
Ul(
{
classes("uk-navbar-nav")
include(*modifiers)
include(UIKitNavbar.Nav, *modifiers)
attributesCustomizer()
}
) {

View File

@@ -1,3 +1,5 @@
package dev.inmo.jsuikit.modifiers
sealed class AttributeValue(val name: String)
sealed class AttributeValue(val name: String) {
override fun toString(): String = name
}

View File

@@ -0,0 +1,8 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitBreadcrumb(
override val classes: Array<String> = emptyArray(),
override val otherAttrs: Map<String, String> = emptyMap()
) : UIKitModifier {
companion object : UIKitBreadcrumb(arrayOf("uk-breadcrumb"))
}

View File

@@ -1,5 +1,9 @@
package dev.inmo.jsuikit.modifiers
import dev.inmo.jsuikit.types.DropdownOptions
import dev.inmo.jsuikit.utils.Milliseconds
import dev.inmo.jsuikit.utils.buildAttribute
sealed class UIKitDropdown(classname: String) : UIKitModifier {
override val classes: Array<String> = arrayOf(classname)
@@ -50,6 +54,9 @@ sealed class UIKitDropdown(classname: String) : UIKitModifier {
object Click : Mode("click")
object Hover : Mode("hover")
object None : Mode("")
object HoverAndClick : Mode("$Hover, $Click")
}
sealed class Flip(name: String) : AttributeValue(name) {
@@ -61,4 +68,48 @@ sealed class UIKitDropdown(classname: String) : UIKitModifier {
}
class Custom(
dropdownOptions: DropdownOptions
) : UIKitDropdown("uk-dropdown") {
override val otherAttrs: Map<String, String> = mapOf(
buildAttribute(
"uk-dropdown"
) {
dropdownOptions.includeParameters(this)
}
)
}
companion object {
operator fun invoke(
dropdownOptions: DropdownOptions
) = Custom(dropdownOptions)
operator fun invoke(
toggle: String? = null,
pos: Position? = null,
mode: Mode? = null,
delayShow: Milliseconds? = null,
delayHide: Milliseconds? = null,
boundary: String? = null,
boundaryAlign: Boolean? = null,
flip: Flip? = null,
offset: Int? = null,
animation: UIKitAnimation? = null,
duration: Milliseconds? = null,
) = Custom(
DropdownOptions(
toggle = toggle,
pos = pos,
mode = mode,
delayShow = delayShow,
delayHide = delayHide,
boundary = boundary,
boundaryAlign = boundaryAlign,
flip = flip,
offset = offset,
animation = animation,
duration = duration
)
)
}
}

View File

@@ -0,0 +1,46 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitList(
vararg classes: String,
override val otherAttrs: Map<String, String> = emptyMap()
) : UIKitModifier {
@Suppress("UNCHECKED_CAST")
override val classes: Array<String> = classes as Array<String>
sealed class Style(vararg classes: String) : UIKitList(*classes) {
object Disc : Style("uk-list-disc")
object Circle : Style("uk-list-circle")
object Square : Style("uk-list-square")
object Decimal : Style("uk-list-decimal")
object Hyphen : Style("uk-list-hyphen")
}
sealed class Size(vararg classes: String) : UIKitList(*classes) {
object Large : Size("uk-list-large")
object Collapse : Size("uk-list-collapse")
}
sealed class Color(vararg classes: String) : UIKitList(*classes) {
object Muted : Color("uk-list-muted")
object Emphasis : Color("uk-list-emphasis")
object Primary : Color("uk-list-primary")
object Secondary : Color("uk-list-secondary")
companion object {
val Bullet = UIKitList.Bullet
}
}
object Bullet: UIKitList("uk-list-bullet")
object Divider: UIKitList("uk-list-divider")
object Striped: UIKitList("uk-list-striped")
companion object : UIKitList("uk-list")
}

View File

@@ -1,6 +1,9 @@
package dev.inmo.jsuikit.modifiers
import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.attributes.AttrsScope
import org.jetbrains.compose.web.dom.AttrBuilderContext
import org.w3c.dom.Element
interface UIKitModifier {
val classes: Array<String>
@@ -15,3 +18,16 @@ fun AttrsScope<*>.include(vararg container: UIKitModifier?) {
it ?.otherAttrs ?.let { attrs -> attrs.forEach { (k, v) -> attr(k, v) } }
}
}
fun <T : Element> UIKitModifier.asAttributesBuilder(): AttrBuilderContext<T> = {
include(this@asAttributesBuilder)
}
operator fun UIKitModifier.plus(other: UIKitModifier): UIKitModifier = UIKitCustom(
classes + other.classes,
otherAttrs + other.otherAttrs
)
fun <T: Element> UIKitModifier?.builder() = Attrs<T>(this).builder
fun <T: Element> Array<out UIKitModifier?>.builder() = Attrs<T>(*this).builder
inline fun <T: Element> attrsBuilder(vararg modifiers: UIKitModifier?) = modifiers.builder<T>()
@JsName("plusBuilder")
operator fun <T: Element> UIKitModifier?.plus(other: UIKitModifier?): AttrBuilderContext<T> = Attrs<T>(this@plus, other).builder

View File

@@ -14,6 +14,8 @@ sealed class UIKitNav(classname: String) : UIKitModifier {
object Center : UIKitNav("uk-nav-center")
object Sub : UIKitNav("uk-nav-sub")
companion object : UIKitNav("uk-nav") {
val SubNav = UIKitSubNav
}

View File

@@ -1,17 +1,86 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitNavbar(suffix: String) : UIKitModifier {
override val classes: Array<String> = arrayOf("uk-navbar-$suffix")
import dev.inmo.jsuikit.types.Dropdown
import dev.inmo.jsuikit.utils.*
object Transparent : UIKitNavbar("transparent")
sealed class Dropdown(suffix: String?) : UIKitNavbar("dropdown${suffix ?.let { "-$it" } ?: ""}") {
sealed class UIKitNavbar(vararg classes: String) : UIKitModifier {
override val classes: Array<String> = classes as Array<String>
object Transparent : UIKitNavbar("uk-navbar-transparent")
object Container : UIKitNavbar("uk-navbar-container")
sealed class Dropdown(suffix: String?) : UIKitNavbar("uk-navbar-dropdown${suffix ?.let { "-$it" } ?: ""}") {
object Nav : Dropdown("nav")
sealed class Width(suffix: String) : Dropdown(suffix) {
object Two : Width("width-2")
object Three : Width("width-3")
object Four : Width("width-4")
object Five : Width("width-5")
}
companion object : Dropdown(null)
}
object Item : UIKitNavbar("item")
sealed class Alignment(val suffix: String) : UIKitNavbar("uk-navbar-$suffix") {
object Left : Alignment("left")
sealed class Center(suffix: String) : Alignment(suffix) {
object Left : Center("center-left")
object Right : Center("center-right")
companion object {
companion object : Center("center")
}
object Right : Alignment("right")
}
object Item : UIKitNavbar("uk-navbar-item")
object Nav : UIKitNavbar("uk-navbar-nav")
object Subtitle : UIKitNavbar("uk-navbar-subtitle")
object Toggle : UIKitNavbar("uk-navbar-toggle")
object Sticky : UIKitNavbar("uk-navbar-sticky")
class Component internal constructor(
override val otherAttrs: Map<String, String>
) : UIKitNavbar(*UIKitNavbar.classes)
companion object : UIKitNavbar("uk-navbar") {
val Logo = UIKitUtility.Logo
operator fun invoke(
align: String?,
mode: String? = null,
delayShow: Milliseconds? = null,
delayHide: Milliseconds? = null,
boundary: String? = null,
boundaryAlign: Boolean? = null,
offset: Pixels? = null,
dropbar: Boolean? = null,
duration: Milliseconds? = null
): Component {
return Component(
mapOf(
buildAttribute(UIKitNavbar.classes.first()) {
"align" to align
"mode" to mode
"delay-show" to delayShow
"delay-hide" to delayHide
"boundary" to boundary
"boundary-align" to boundaryAlign
"offset" to offset
"dropbar" to dropbar
"duration" to duration
}
)
)
}
operator fun invoke(
align: Alignment? = null,
mode: UIKitDropdown.Mode? = null,
delayShow: Milliseconds? = null,
delayHide: Milliseconds? = null,
boundary: String? = null,
boundaryAlign: Boolean? = null,
offset: Pixels? = null,
dropbar: Boolean? = null,
duration: Milliseconds? = null
): Component = invoke(align ?.suffix, mode ?.name, delayShow, delayHide, boundary, boundaryAlign, offset, dropbar, duration)
}
}

View File

@@ -8,7 +8,10 @@ sealed class UIKitPadding(suffix: String?) : UIKitModifier {
object Small : Size("small")
object Large : Size("large")
companion object : Size(null)
companion object : Size(null) {
val Default
get() = this
}
}
@@ -25,5 +28,6 @@ sealed class UIKitPadding(suffix: String?) : UIKitModifier {
}
companion object : Size(null)
}

View File

@@ -0,0 +1,23 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitSection(vararg classes: String) : UIKitModifier {
override val classes: Array<String> = classes as Array<String>
sealed class Style(suffix: String) : UIKitSection("uk-section-$suffix") {
object Default : Style("default")
object Muted : Style("muted")
object Primary : Style("primary")
object Secondary : Style("secondary")
}
sealed class Size(suffix: String) : UIKitSection("uk-section-$suffix") {
object XSmall : Size("xsmall")
object Small : Size("small")
object Large : Size("large")
object XLarge : Size("xlarge")
}
object Overlap : UIKitSection("uk-section-overlap")
companion object : UIKitSection("uk-section")
}

View File

@@ -38,7 +38,10 @@ sealed class UIKitUtility(classname: String) : UIKitModifier {
object Width : Responsive("width")
object Height : Responsive("height")
}
object PreserveWidth : UIKitUtility("uk-preserve-width")
sealed class Preserve(suffix: String) : UIKitUtility("uk-preserve-$suffix") {
object Width : Preserve("width")
object Color : Preserve("color")
}
sealed class Border(suffix: String) : UIKitUtility("uk-border-$suffix") {
object Rounded : Border("rounded")
@@ -112,4 +115,8 @@ sealed class UIKitUtility(classname: String) : UIKitModifier {
object Open : UIKitUtility("uk-open")
object Link : UIKitUtility("uk-link")
companion object {
val PreserveWidth = Preserve.Width
}
}

View File

@@ -0,0 +1,44 @@
package dev.inmo.jsuikit.types
import dev.inmo.jsuikit.modifiers.UIKitAnimation
import dev.inmo.jsuikit.modifiers.UIKitDropdown
import dev.inmo.jsuikit.utils.*
external interface Dropdown {
fun show()
fun hide(delay: Boolean = definedExternally)
fun hide(delay: Milliseconds)
}
data class DropdownOptions(
private val toggle: String? = null,
private val pos: UIKitDropdown.Position? = null,
private val mode: UIKitDropdown.Mode? = null,
private val delayShow: Milliseconds? = null,
private val delayHide: Milliseconds? = null,
private val boundary: String? = null,
private val boundaryAlign: Boolean? = null,
private val flip: UIKitDropdown.Flip? = null,
private val offset: Int? = null,
private val animation: UIKitAnimation? = null,
private val duration: Milliseconds? = null,
) {
fun includeParameters(parametersBuilder: ParametersBuilder) {
with(parametersBuilder) {
"toggle" to toggle
"pos" to pos
"mode" to mode
"delayShow" to delayShow
"delayHide" to delayHide
"boundary" to boundary
"boundaryAlign" to boundaryAlign
"flip" to flip
"offset" to offset
"animation" to animation
"duration" to duration
}
}
fun parameters() = buildParametersWithoutNulls {
includeParameters(this)
}
}

View File

@@ -13,4 +13,7 @@ external interface UIKit {
fun modal(element: Element): UIKitDialog
fun modal(selector: String): UIKitDialog?
fun dropdown(element: Element, options: DropdownOptions = definedExternally): Dropdown
fun dropdown(selector: String, options: DropdownOptions = definedExternally): Dropdown?
}

View File

@@ -2,26 +2,24 @@ package dev.inmo.jsuikit.utils
class AttributeBuilder (
val attributeName: String,
val skipNullValues: Boolean = true,
private val parametersPreset: MutableMap<String, String?> = mutableMapOf()
val parametersBuilder: ParametersBuilder
) {
fun add(k: String, v: Any? = null) {
if (v != null || !skipNullValues) {
parametersPreset[k] = v ?.toString()
}
fun build(): Pair<String, String> = parametersBuilder.build().run {
Pair(
attributeName, toList().joinToString(";") {
"${it.first}${it.second ?.let { ": $it" } ?: ""}"
}
)
}
infix fun String.to(value: Any?) = add(this, value)
operator fun String.unaryPlus() = add(this, null)
fun build(): Pair<String, String> = Pair(
attributeName, parametersPreset.toList().joinToString(";") {
"${it.first}${it.second ?.let { ": $it" } ?: ""}"
}
)
}
inline fun buildAttribute(attributeName: String, skipNullValues: Boolean = true, block: AttributeBuilder.() -> Unit) = AttributeBuilder(
inline fun buildAttribute(
attributeName: String,
skipNullValues: Boolean = true,
block: ParametersBuilder.() -> Unit
) = AttributeBuilder(
attributeName,
skipNullValues
).apply(block).build()
ParametersBuilder(skipNullValues)
).apply {
parametersBuilder.block()
}.build()

View File

@@ -0,0 +1,32 @@
package dev.inmo.jsuikit.utils
import dev.inmo.jsuikit.modifiers.UIKitModifier
import org.jetbrains.compose.web.attributes.AttrsScope
import org.jetbrains.compose.web.dom.ContentBuilder
import org.w3c.dom.Element
typealias AttrsWithContentBuilder<T> = Pair<Attrs<T>, ContentBuilder<T>>
@Suppress("NOTHING_TO_INLINE")
inline fun <T : Element> AttrsWithContentBuilder(
vararg modifiers: UIKitModifier?,
noinline attrs: AttrsScope<T>.() -> Unit = {},
noinline builder: ContentBuilder<T>
) = AttrsWithContentBuilder(
Attrs(*modifiers, attrs = attrs),
builder
)
@Suppress("NOTHING_TO_INLINE")
inline fun <T : Element> AttrsWithContentBuilder(attrs: Attrs<T>) = AttrsWithContentBuilder(
attrs
) {}
inline val <T : Element> AttrsWithContentBuilder<T>.attrs
get() = first
inline val <T : Element> AttrsWithContentBuilder<T>.attributesBuilderContext
get() = attrs.builder
inline val <T : Element> AttrsWithContentBuilder<T>.builder
get() = second

View File

@@ -1,55 +0,0 @@
package dev.inmo.jsuikit.utils
import androidx.compose.runtime.Composable
import kotlinx.browser.document
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.*
private object DListElementBuilder : ElementBuilder<HTMLDListElement> {
private val el: Element by lazy { document.createElement("dl") }
override fun create(): HTMLDListElement = el.cloneNode() as HTMLDListElement
}
private object DTermElementBuilder : ElementBuilder<HTMLElement> {
private val el: Element by lazy { document.createElement("dt") }
override fun create(): HTMLElement = el.cloneNode() as HTMLElement
}
private object DDescriptionElementBuilder : ElementBuilder<HTMLElement> {
private val el: Element by lazy { document.createElement("dd") }
override fun create(): HTMLElement = el.cloneNode() as HTMLElement
}
@Composable
fun DList(
attrs: AttrBuilderContext<HTMLDListElement>? = null,
content: ContentBuilder<HTMLDListElement>? = null
) {
TagElement(
DListElementBuilder,
attrs,
content
)
}
@Composable
fun DTerm(
attrs: AttrBuilderContext<HTMLElement>? = null,
content: ContentBuilder<HTMLElement>? = null
) {
TagElement(
DTermElementBuilder,
attrs,
content
)
}
@Composable
fun DDescription(
attrs: AttrBuilderContext<HTMLElement>? = null,
content: ContentBuilder<HTMLElement>? = null
) {
TagElement(
DDescriptionElementBuilder,
attrs,
content
)
}

View File

@@ -0,0 +1,38 @@
package dev.inmo.jsuikit.utils
class ParametersBuilder(
val skipNullValues: Boolean = true,
private val parameters: MutableMap<String, String?> = mutableMapOf()
) {
fun add(k: String, v: Any? = null) {
if (v != null || !skipNullValues) {
parameters[k] = v ?.toString()
}
}
infix fun String.to(value: Any?) = add(this, value)
operator fun String.unaryPlus() = add(this, null)
operator fun Map<String, String?>.unaryPlus() = forEach {
}
fun build() = parameters.toMap()
fun buildNotNullable() = parameters.mapNotNull { (k, v) ->
if (v != null) {
Pair(k, v)
} else {
null
}
}.toMap()
}
fun buildParameters(
skipNullValues: Boolean = true,
block: ParametersBuilder.() -> Unit
) = ParametersBuilder(skipNullValues).apply(block).build()
fun buildParametersWithoutNulls(
skipNullValues: Boolean = true,
block: ParametersBuilder.() -> Unit
) = ParametersBuilder(skipNullValues).apply(block).buildNotNullable()