Compare commits

..

70 Commits

Author SHA1 Message Date
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
4a204f8971 fixes in icons 2022-03-25 19:27:02 +06:00
fa41022df5 use iterables in navs 2022-03-25 17:13:50 +06:00
04a94cfabe add onClick callback into Close#drawAsButton 2022-03-25 16:56:39 +06:00
c337dd2b2d add composable annotations to close functions 2022-03-25 16:46:14 +06:00
b4a0ff6ece add support of close element 2022-03-25 16:45:30 +06:00
061b55b164 start 0.0.47 2022-03-25 16:44:50 +06:00
d93517bf83 Merge pull request #47 from InsanusMokrassar/0.0.46
0.0.46
2022-03-24 18:17:00 +06:00
8497739c10 add support of UIKitInverse and UIKitOverlay 2022-03-24 17:23:52 +06:00
7fb24d1999 start 0.0.46 2022-03-24 17:23:24 +06:00
bdd955d6e9 Update CHANGELOG.md 2022-03-16 16:28:32 +06:00
6144ee5723 Merge pull request #46 from InsanusMokrassar/0.0.45
0.0.45
2022-03-16 16:04:17 +06:00
1f44f27fbb add container support 2022-03-16 16:03:35 +06:00
c59c442a36 start 0.0.45 2022-03-16 16:03:08 +06:00
e61f420dc4 Merge pull request #45 from InsanusMokrassar/0.0.44
0.0.44
2022-03-13 16:46:46 +06:00
e0052950e9 Update CHANGELOG.md 2022-03-13 14:04:50 +06:00
47eab8821d Update libs.versions.toml 2022-03-13 14:03:13 +06:00
b89df98459 start 0.0.44 2022-03-13 14:02:46 +06:00
f90055fa59 Merge pull request #44 from InsanusMokrassar/0.0.43
0.0.43
2022-03-12 01:45:19 +06:00
38a884cc16 add defaults in content builders of Grid and GridColumn 2022-03-12 00:16:57 +06:00
43e3ed742d update gradle wrapper 2022-03-12 00:07:32 +06:00
3ddb22341c additions in UIKitScreenSizeModifier and support of Tile 2022-03-12 00:06:47 +06:00
475afeb78b start 0.0.43 2022-03-12 00:05:54 +06:00
af289b3194 Merge pull request #43 from InsanusMokrassar/0.0.42
0.0.42
2022-03-06 16:23:38 +06:00
7bd5b26a1b migration to compose 1.1.0 and replaces according to it 2022-03-06 16:18:21 +06:00
4e22cfce1a start 0.0.42 2022-03-06 16:18:01 +06:00
60816700ea Merge pull request #42 from InsanusMokrassar/0.0.41
0.0.41
2022-03-03 00:59:28 +06:00
33fbd2c0be now it is possible to include nullable modifiers in attrs 2022-03-02 21:57:55 +06:00
b836fe744e DescriptionList 2022-03-02 20:27:23 +06:00
f77c21ac51 fixes in DropAre and new type of attrs 2022-03-02 18:40:07 +06:00
c720973bfc UIKitForm#Custom now will also include class uk-form-custom 2022-03-02 18:06:41 +06:00
0b11e2c1b9 add UIKitUtility#Link 2022-03-02 17:59:52 +06:00
556ab4e090 add DropAre, UIKitPlaceholder and UIKitForm#Custom now have nullable target 2022-03-02 16:52:58 +06:00
a596516c79 start 0.0.41 2022-03-02 16:52:24 +06:00
8eeabc4b5d Merge pull request #41 from InsanusMokrassar/0.0.40
0.0.40
2022-03-01 22:29:14 +06:00
49 changed files with 847 additions and 131 deletions

View File

@@ -1,5 +1,74 @@
# Changelog # Changelog
## 0.1.0
* `Kotlin` = `1.6.21`
* `Compose`: `1.2.0-alpha01-dev682`
## 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
## 0.0.46
* Add support of `UIKitOverlay`
* Add support of `UIKitInverse`
## 0.0.45
* Add support of containers in `UIKitContainer` modifiers and `Container` function
## 0.0.44
* `Versions`:
* `Compose`: `1.1.0` -> `1.1.1`
## 0.0.43
* Several new extensions for `UIKitModifier` like `UIKitModifier#onSmallScreen`
* Support of `Tile`
## 0.0.42
* Migration to compose 1.1.0
* Replaces according to it
## 0.0.41
* Add `DropArea`
* Add `UIKitPlaceholder`
* `UIKitForm#Custom` now have nullable param target
* Add `UIKitUtility#Link`
* Add `DescriptionList` and several support composable functions
## 0.0.40 ## 0.0.40
* All `DefaultTable` functions now use `Iterable` as data type * All `DefaultTable` functions now use `Iterable` as data type

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,9 +1,8 @@
package dev.inmo.jsuikit package dev.inmo.jsuikit
import dev.inmo.jsuikit.modifiers.AttributeValue import dev.inmo.jsuikit.modifiers.AttributeValue
import dev.inmo.jsuikit.utils.AttributeBuilder import dev.inmo.jsuikit.utils.*
import dev.inmo.jsuikit.utils.buildAttribute import org.jetbrains.compose.web.attributes.AttrsScope
import org.jetbrains.compose.web.attributes.AttrsBuilder
@Deprecated("Will be removed soon") @Deprecated("Will be removed soon")
class UIKitAttributeValueBuilder { class UIKitAttributeValueBuilder {
@@ -22,10 +21,10 @@ class UIKitAttributeValueBuilder {
fun build(): String = attrs.joinToString(";") { (k, v) -> "$k: $v" } fun build(): String = attrs.joinToString(";") { (k, v) -> "$k: $v" }
} }
fun AttrsBuilder<*>.buildAndAddAttribute( fun AttrsScope<*>.buildAndAddAttribute(
attributeName: String, attributeName: String,
skipNullValues: Boolean = true, skipNullValues: Boolean = true,
block: AttributeBuilder.() -> Unit block: ParametersBuilder.() -> Unit
) { ) {
buildAttribute(attributeName, skipNullValues, block).let { buildAttribute(attributeName, skipNullValues, block).let {
attr(it.first, it.second) attr(it.first, it.second)

View File

@@ -4,7 +4,7 @@ import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.UIKitAccordion import dev.inmo.jsuikit.modifiers.UIKitAccordion
import dev.inmo.jsuikit.modifiers.include import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.utils.Attrs import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.attributes.AttrsBuilder import org.jetbrains.compose.web.attributes.AttrsScope
import org.jetbrains.compose.web.dom.* import org.jetbrains.compose.web.dom.*
import org.w3c.dom.* import org.w3c.dom.*
@@ -12,7 +12,7 @@ import org.w3c.dom.*
fun <T> Accordion( fun <T> Accordion(
data: Iterable<T>, data: Iterable<T>,
attrs: Attrs<HTMLUListElement> = Attrs.empty(), attrs: Attrs<HTMLUListElement> = Attrs.empty(),
itemAttrsBuilder: AttrsBuilder<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> }, itemAttrsBuilder: AttrsScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
itemContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit itemContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit
) { ) {
Ul( Ul(
@@ -33,13 +33,13 @@ fun <T> Accordion(
fun <T> DefaultAccordion( fun <T> DefaultAccordion(
data: Iterable<T>, data: Iterable<T>,
attrs: Attrs<HTMLUListElement> = Attrs.empty(), attrs: Attrs<HTMLUListElement> = Attrs.empty(),
itemAttrsBuilder: AttrsBuilder<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> }, itemAttrsBuilder: AttrsScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
titleAttrsBuilder: AttrsBuilder<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> }, titleAttrsBuilder: AttrsScope<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
titleContentBuilder: @Composable ElementScope<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> }, titleContentBuilder: @Composable ElementScope<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
beforeTitleContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> }, beforeTitleContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
afterTitleContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> }, afterTitleContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
afterContentContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> }, afterContentContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
contentAttrsBuilder: AttrsBuilder<HTMLDivElement>.(Int, T) -> Unit = { _, _ -> }, contentAttrsBuilder: AttrsScope<HTMLDivElement>.(Int, T) -> Unit = { _, _ -> },
contentContentBuilder: @Composable ElementScope<HTMLDivElement>.(Int, T) -> Unit contentContentBuilder: @Composable ElementScope<HTMLDivElement>.(Int, T) -> Unit
) = Accordion( ) = Accordion(
data, data,
@@ -72,9 +72,9 @@ fun <T> DefaultAccordion(
data: Iterable<T>, data: Iterable<T>,
titleResolver: (Int, T) -> String, titleResolver: (Int, T) -> String,
attrs: Attrs<HTMLUListElement> = Attrs.empty(), attrs: Attrs<HTMLUListElement> = Attrs.empty(),
itemAttrsBuilder: AttrsBuilder<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> }, itemAttrsBuilder: AttrsScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
titleAttrsBuilder: AttrsBuilder<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> }, titleAttrsBuilder: AttrsScope<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
contentAttrsBuilder: AttrsBuilder<HTMLDivElement>.(Int, T) -> Unit = { _, _ -> }, contentAttrsBuilder: AttrsScope<HTMLDivElement>.(Int, T) -> Unit = { _, _ -> },
contentContentBuilder: @Composable ElementScope<HTMLDivElement>.(Int, T) -> Unit contentContentBuilder: @Composable ElementScope<HTMLDivElement>.(Int, T) -> Unit
) = DefaultAccordion( ) = DefaultAccordion(
data, data,

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,7 +4,8 @@ import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.* import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.Attrs import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.dom.* import org.jetbrains.compose.web.dom.*
import org.w3c.dom.* import org.w3c.dom.HTMLDivElement
import org.w3c.dom.HTMLHeadingElement
@Composable @Composable
fun Card( fun Card(

View File

@@ -0,0 +1,45 @@
package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import androidx.compose.web.events.SyntheticMouseEvent
import dev.inmo.jsuikit.modifiers.UIKitClose
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.attributes.ButtonType
import org.jetbrains.compose.web.attributes.type
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLAnchorElement
import org.w3c.dom.HTMLButtonElement
object Close {
@Composable
fun drawAsLink(
href: String = "#",
attrs: Attrs<HTMLAnchorElement> = Attrs.empty(),
contentBuilder: ContentBuilder<HTMLAnchorElement> = {}
) = A(
href,
{
include(UIKitClose)
attrs.builder(this)
},
contentBuilder
)
@Composable
fun drawAsButton(
attrs: Attrs<HTMLButtonElement> = Attrs.empty(),
contentBuilder: ContentBuilder<HTMLButtonElement> = {},
onClick: ((SyntheticMouseEvent) -> Unit)? = null
) = Button(
{
type(ButtonType.Button)
include(UIKitClose)
attrs.builder(this)
onClick ?.let {
onClick(onClick)
}
},
contentBuilder
)
}

View File

@@ -0,0 +1,21 @@
package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.UIKitContainer
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.dom.ContentBuilder
import org.jetbrains.compose.web.dom.Div
import org.w3c.dom.HTMLDivElement
@Composable
fun Container(
attrs: Attrs<HTMLDivElement> = Attrs.empty(),
contentBuilder: ContentBuilder<HTMLDivElement> = {}
) = Div(
{
include(UIKitContainer)
attrs.builder.invoke(this)
},
contentBuilder
)

View File

@@ -0,0 +1,57 @@
package dev.inmo.jsuikit.elements
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.w3c.dom.HTMLDListElement
import org.w3c.dom.HTMLElement
@Composable
fun DescriptionList(
attrs: Attrs<HTMLDListElement>,
contentBuilder: ContentBuilder<HTMLDListElement>
) {
DList(
{
include(UIKitDescriptionList)
attrs.builder(this)
},
contentBuilder
)
}
@Composable
fun <T> DescriptionList(
data: Iterable<T>,
attrs: Attrs<HTMLDListElement>,
beforeTermContent: (@Composable ElementScope<HTMLElement>.(Int, T) -> Unit)? = null,
itemTermAttrs: ((Int, T) -> Attrs<HTMLElement>?)? = null,
itemTermContent: (@Composable ElementScope<HTMLElement>.(Int, T) -> Unit)? = null,
betweenTermAndDescriptionContent: (@Composable ElementScope<HTMLElement>.(Int, T) -> Unit)? = null,
afterDescriptionContent: (@Composable ElementScope<HTMLElement>.(Int, T) -> Unit)? = null,
itemDescriptionAttrs: ((Int, T) -> Attrs<HTMLElement>?)? = null,
itemDescriptionContent: (@Composable ElementScope<HTMLElement>.(Int, T) -> Unit)? = null
) {
DescriptionList(attrs) {
data.forEachIndexed { i, t ->
beforeTermContent ?.invoke(this, i, t)
if (itemTermAttrs != null || itemTermContent != null) {
DTerm(
itemTermAttrs ?.let { { it(i, t) } },
itemTermContent ?.let { { it(i, t) } },
)
}
betweenTermAndDescriptionContent ?.invoke(this, i, t)
if (itemDescriptionAttrs != null || itemDescriptionContent != null) {
DDescription(
itemDescriptionAttrs ?.let { { it(i, t) } },
itemDescriptionContent ?.let { { it(i, t) } },
)
}
afterDescriptionContent ?.invoke(this, i, t)
}
}
}

View File

@@ -4,8 +4,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffectResult import androidx.compose.runtime.DisposableEffectResult
import dev.inmo.jsuikit.modifiers.* import dev.inmo.jsuikit.modifiers.*
import org.jetbrains.compose.web.dom.* import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.dom.Text import org.w3c.dom.HTMLDivElement
import org.w3c.dom.* import org.w3c.dom.HTMLElement
import org.w3c.dom.events.Event import org.w3c.dom.events.Event
import kotlin.random.Random import kotlin.random.Random
import kotlin.random.nextUInt import kotlin.random.nextUInt

View File

@@ -0,0 +1,25 @@
package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.Attrs
import dev.inmo.jsuikit.utils.InputAttrs
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLDivElement
@Composable
fun DropArea(
attrs: Attrs<HTMLDivElement> = Attrs.empty(),
inputAttrs: InputAttrs<String> = Attrs.empty(),
contentBuilder: ContentBuilder<HTMLDivElement> = {}
) = Div(
{
include(UIKitPlaceholder, UIKitForm.Custom())
attrs.builder(this)
}
) {
FileInput {
inputAttrs.builder.invoke(this)
}
contentBuilder(this)
}

View File

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

View File

@@ -10,7 +10,7 @@ import org.w3c.dom.HTMLDivElement
fun GridColumn( fun GridColumn(
vararg modifiers: UIKitModifier, vararg modifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLDivElement> = {}, attributesCustomizer: AttrBuilderContext<HTMLDivElement> = {},
builder: @Composable ElementScope<HTMLDivElement>.() -> Unit builder: @Composable ElementScope<HTMLDivElement>.() -> Unit = {}
) { ) {
Div( Div(
{ {
@@ -30,7 +30,7 @@ fun Grid(
marginClass: String? = null, marginClass: String? = null,
firstColumnClass: String? = null, firstColumnClass: String? = null,
attributesCustomizer: AttrBuilderContext<HTMLDivElement> = {}, attributesCustomizer: AttrBuilderContext<HTMLDivElement> = {},
builder: @Composable ElementScope<HTMLDivElement>.() -> Unit builder: @Composable ElementScope<HTMLDivElement>.() -> Unit = {}
) { ) {
val attrs = listOfNotNull( val attrs = listOfNotNull(
if (masonry) "masonry" to "true" else null, if (masonry) "masonry" to "true" else null,

View File

@@ -77,15 +77,15 @@ sealed class Icon(val name: String) {
object Grid : App("grid") object Grid : App("grid")
sealed class More(iconName: String) : App("more${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") { sealed class More(iconName: String) : App("more${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") {
object Vertical : More("vertical") object Vertical : More("vertical")
companion object : More("more") companion object : More("")
} }
sealed class Plus(iconName: String) : App("plus${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") { sealed class Plus(iconName: String) : App("plus${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") {
object Circle : Plus("circle") object Circle : Plus("circle")
companion object : Plus("plus") companion object : Plus("")
} }
sealed class Minus(iconName: String) : App("minus${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") { sealed class Minus(iconName: String) : App("minus${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") {
object Circle : Minus("circle") object Circle : Minus("circle")
companion object : Minus("minus") companion object : Minus("")
} }
object Close : App("close") object Close : App("close")
object Check : App("check") object Check : App("check")
@@ -93,7 +93,7 @@ sealed class Icon(val name: String) {
object Refresh : App("refresh") object Refresh : App("refresh")
sealed class Play(iconName: String) : App("play${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") { sealed class Play(iconName: String) : App("play${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") {
object Circle : Play("circle") object Circle : Play("circle")
companion object : Play("play") companion object : Play("")
} }
} }
sealed class Devices(iconName: String) : Icon(iconName) { sealed class Devices(iconName: String) : Icon(iconName) {
@@ -102,11 +102,11 @@ sealed class Icon(val name: String) {
object Laptop : Devices("laptop") object Laptop : Devices("laptop")
sealed class Tablet(iconName: String) : Devices("tablet${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") { sealed class Tablet(iconName: String) : Devices("tablet${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") {
object Landscape : Tablet("landscape") object Landscape : Tablet("landscape")
companion object : Tablet("tablet") companion object : Tablet("")
} }
sealed class Phone(iconName: String) : Devices("phone${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") { sealed class Phone(iconName: String) : Devices("phone${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") {
object Landscape : Phone("landscape") object Landscape : Phone("landscape")
companion object : Phone("phone") companion object : Phone("")
} }
} }
sealed class Storage(iconName: String) : Icon(iconName) { sealed class Storage(iconName: String) : Icon(iconName) {
@@ -114,7 +114,7 @@ sealed class Icon(val name: String) {
object Text : File("text") object Text : File("text")
object Pdf : File("pdf") object Pdf : File("pdf")
object Edit : File("edit") object Edit : File("edit")
companion object : File("file") companion object : File("")
} }
object Copy : Storage("copy") object Copy : Storage("copy")
object Folder : Storage("folder") object Folder : Storage("folder")
@@ -177,7 +177,7 @@ sealed class Icon(val name: String) {
object Foursquare : Brands("foursquare") object Foursquare : Brands("foursquare")
sealed class Github(iconName: String) : Brands("github${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") { sealed class Github(iconName: String) : Brands("github${iconName.takeIf { it.isNotEmpty() } ?.let { "-$it" } ?: "" }") {
object Alt : Github("alt") object Alt : Github("alt")
companion object : Github("github") companion object : Github("")
} }
object Gitter : Brands("gitter") object Gitter : Brands("gitter")
object Google : Brands("google") object Google : Brands("google")

View File

@@ -1,9 +1,11 @@
package dev.inmo.jsuikit.elements package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.* import dev.inmo.jsuikit.modifiers.UIKitLabel
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.utils.Attrs import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.dom.* import org.jetbrains.compose.web.dom.Span
import org.jetbrains.compose.web.dom.Text
import org.w3c.dom.HTMLSpanElement import org.w3c.dom.HTMLSpanElement
@Composable @Composable

View File

@@ -2,14 +2,32 @@ package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.runtime.snapshots.SnapshotStateList
import dev.inmo.jsuikit.modifiers.UIKitModifier import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.modifiers.include import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.dom.* import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLHeadingElement import org.w3c.dom.HTMLHeadingElement
import org.w3c.dom.HTMLUListElement import org.w3c.dom.HTMLUListElement
@Composable @Composable
fun <T> List( 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, title: String,
data: SnapshotStateList<T>, data: SnapshotStateList<T>,
vararg titleModifiers: UIKitModifier, vararg titleModifiers: UIKitModifier,
@@ -23,15 +41,27 @@ fun <T> List(
Text(title) Text(title)
} }
besidesTitleAndList ?.invoke() besidesTitleAndList ?.invoke()
Ul( List(data, Attrs(*ulModifiers) { ulCustomizer(this) }, elementAllocator)
{
classes("uk-list")
include(*ulModifiers)
ulCustomizer()
}
) {
data.forEach {
elementAllocator(it)
}
}
} }
@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 package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.snapshots.SnapshotStateList
import dev.inmo.jsuikit.buildAndAddAttribute import dev.inmo.jsuikit.buildAndAddAttribute
import dev.inmo.jsuikit.modifiers.* import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.utils.Milliseconds import dev.inmo.jsuikit.utils.Milliseconds
@@ -94,8 +93,8 @@ fun SubNav(
@Composable @Composable
fun <T> Nav( fun <T> Nav(
title: String, title: String?,
data: SnapshotStateList<T>, data: Iterable<T>,
vararg ulModifiers: UIKitModifier, vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(), titleModifiers: Array<UIKitModifier> = emptyArray(),
multiple: Boolean? = null, multiple: Boolean? = null,
@@ -104,6 +103,7 @@ fun <T> Nav(
duration: Milliseconds? = null, duration: Milliseconds? = null,
besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null, besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null,
titleCustomizer: AttrBuilderContext<HTMLLIElement> = {}, titleCustomizer: AttrBuilderContext<HTMLLIElement> = {},
afterTitleContentBuilder: ContentBuilder<HTMLLIElement> = {},
ulCustomizer: AttrBuilderContext<HTMLUListElement> = {}, ulCustomizer: AttrBuilderContext<HTMLUListElement> = {},
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) { ) {
@@ -119,11 +119,14 @@ fun <T> Nav(
ulCustomizer() ulCustomizer()
} }
) { ) {
NavHeader( title ?.let {
title, NavHeader(
*titleModifiers, title,
attributesCustomizer = titleCustomizer *titleModifiers,
) attributesCustomizer = titleCustomizer,
afterTitleContentBuilder = afterTitleContentBuilder
)
}
besidesTitleAndList ?.let { it() } besidesTitleAndList ?.let { it() }
data.forEach { data.forEach {
elementAllocator(it) elementAllocator(it)
@@ -133,8 +136,8 @@ fun <T> Nav(
@Composable @Composable
fun <T> DefaultNav( fun <T> DefaultNav(
title: String, title: String?,
data: SnapshotStateList<T>, data: Iterable<T>,
vararg ulModifiers: UIKitModifier, vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(), titleModifiers: Array<UIKitModifier> = emptyArray(),
multiple: Boolean? = null, multiple: Boolean? = null,
@@ -143,6 +146,7 @@ fun <T> DefaultNav(
duration: Milliseconds? = null, duration: Milliseconds? = null,
besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null, besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null,
titleCustomizer: AttrBuilderContext<HTMLLIElement> = {}, titleCustomizer: AttrBuilderContext<HTMLLIElement> = {},
afterTitleContentBuilder: ContentBuilder<HTMLLIElement> = {},
ulCustomizer: AttrBuilderContext<HTMLUListElement> = {}, ulCustomizer: AttrBuilderContext<HTMLUListElement> = {},
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) = Nav( ) = Nav(
@@ -156,14 +160,15 @@ fun <T> DefaultNav(
duration, duration,
besidesTitleAndList, besidesTitleAndList,
titleCustomizer, titleCustomizer,
afterTitleContentBuilder,
ulCustomizer, ulCustomizer,
elementAllocator elementAllocator
) )
@Composable @Composable
fun <T> PrimaryNav( fun <T> PrimaryNav(
title: String, title: String?,
data: SnapshotStateList<T>, data: Iterable<T>,
vararg ulModifiers: UIKitModifier, vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(), titleModifiers: Array<UIKitModifier> = emptyArray(),
multiple: Boolean? = null, multiple: Boolean? = null,
@@ -172,6 +177,7 @@ fun <T> PrimaryNav(
duration: Milliseconds? = null, duration: Milliseconds? = null,
besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null, besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null,
titleCustomizer: AttrBuilderContext<HTMLLIElement> = {}, titleCustomizer: AttrBuilderContext<HTMLLIElement> = {},
afterTitleContentBuilder: ContentBuilder<HTMLLIElement> = {},
ulCustomizer: AttrBuilderContext<HTMLUListElement> = {}, ulCustomizer: AttrBuilderContext<HTMLUListElement> = {},
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) = Nav( ) = Nav(
@@ -185,14 +191,15 @@ fun <T> PrimaryNav(
duration, duration,
besidesTitleAndList, besidesTitleAndList,
titleCustomizer, titleCustomizer,
afterTitleContentBuilder,
ulCustomizer, ulCustomizer,
elementAllocator elementAllocator
) )
@Composable @Composable
fun <T> SubNav( fun <T> SubNav(
title: String, title: String?,
data: SnapshotStateList<T>, data: Iterable<T>,
vararg ulModifiers: UIKitModifier, vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(), titleModifiers: Array<UIKitModifier> = emptyArray(),
multiple: Boolean? = null, multiple: Boolean? = null,
@@ -201,6 +208,7 @@ fun <T> SubNav(
duration: Milliseconds? = null, duration: Milliseconds? = null,
besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null, besidesTitleAndList: ContentBuilder<HTMLUListElement>? = null,
titleCustomizer: AttrBuilderContext<HTMLLIElement> = {}, titleCustomizer: AttrBuilderContext<HTMLLIElement> = {},
afterTitleContentBuilder: ContentBuilder<HTMLLIElement> = {},
ulCustomizer: AttrBuilderContext<HTMLUListElement> = {}, ulCustomizer: AttrBuilderContext<HTMLUListElement> = {},
elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit elementAllocator: @Composable ElementScope<HTMLUListElement>.(T) -> Unit
) = Nav( ) = Nav(
@@ -214,6 +222,7 @@ fun <T> SubNav(
duration, duration,
besidesTitleAndList, besidesTitleAndList,
titleCustomizer, titleCustomizer,
afterTitleContentBuilder,
ulCustomizer, ulCustomizer,
elementAllocator elementAllocator
) )
@@ -223,6 +232,7 @@ fun NavHeader(
text: String, text: String,
vararg modifiers: UIKitModifier, vararg modifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLLIElement> = {}, attributesCustomizer: AttrBuilderContext<HTMLLIElement> = {},
afterTitleContentBuilder: ContentBuilder<HTMLLIElement> = {}
) { ) {
Li( Li(
{ {
@@ -231,6 +241,7 @@ fun NavHeader(
} }
) { ) {
Text(text) Text(text)
afterTitleContentBuilder()
} }
} }
@@ -238,6 +249,7 @@ fun NavHeader(
fun NavItemElement( fun NavItemElement(
vararg modifiers: UIKitModifier, vararg modifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLLIElement> = {}, attributesCustomizer: AttrBuilderContext<HTMLLIElement> = {},
anchorAttributesCustomizer: AttrBuilderContext<HTMLAnchorElement> = {},
contentAllocator: ContentBuilder<HTMLAnchorElement> contentAllocator: ContentBuilder<HTMLAnchorElement>
) { ) {
Li( Li(
@@ -246,7 +258,7 @@ fun NavItemElement(
attributesCustomizer() attributesCustomizer()
} }
) { ) {
A("#") { A("#", attrs = anchorAttributesCustomizer) {
contentAllocator() contentAllocator()
} }
} }

View File

@@ -3,21 +3,21 @@ package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.UIKitModifier import dev.inmo.jsuikit.modifiers.UIKitModifier
import dev.inmo.jsuikit.modifiers.include import dev.inmo.jsuikit.modifiers.include
import org.jetbrains.compose.web.attributes.AttrsBuilder import org.jetbrains.compose.web.attributes.AttrsScope
import org.jetbrains.compose.web.dom.* import org.jetbrains.compose.web.dom.*
import org.w3c.dom.HTMLLIElement import org.w3c.dom.HTMLLIElement
import org.w3c.dom.HTMLUListElement import org.w3c.dom.HTMLUListElement
interface NavbarNavElement { interface NavbarNavElement {
fun AttrsBuilder<HTMLLIElement>.setup() {} fun AttrsScope<HTMLLIElement>.setup() {}
@Composable @Composable
fun ElementScope<HTMLLIElement>.fill() fun ElementScope<HTMLLIElement>.fill()
class Default( class Default(
private val setupCallback: AttrsBuilder<HTMLLIElement>.() -> Unit, private val setupCallback: AttrsScope<HTMLLIElement>.() -> Unit,
private val fillCallback: @Composable ElementScope<HTMLLIElement>.() -> Unit private val fillCallback: @Composable ElementScope<HTMLLIElement>.() -> Unit
) : NavbarNavElement { ) : NavbarNavElement {
override fun AttrsBuilder<HTMLLIElement>.setup() { override fun AttrsScope<HTMLLIElement>.setup() {
setupCallback() setupCallback()
} }

View File

@@ -1,9 +1,7 @@
package dev.inmo.jsuikit.elements package dev.inmo.jsuikit.elements
import dev.inmo.jsuikit.modifiers.UIKit import dev.inmo.jsuikit.modifiers.UIKit
import dev.inmo.jsuikit.types.UIKitNotificationParameter import dev.inmo.jsuikit.types.*
import dev.inmo.jsuikit.types.NotificationsGroup
import dev.inmo.jsuikit.types.invoke
import dev.inmo.jsuikit.utils.Milliseconds import dev.inmo.jsuikit.utils.Milliseconds
fun Notification( fun Notification(

View File

@@ -1,9 +1,9 @@
package dev.inmo.jsuikit.elements package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.snapshots.SnapshotStateList import dev.inmo.jsuikit.modifiers.UIKitModifier
import dev.inmo.jsuikit.modifiers.* import dev.inmo.jsuikit.modifiers.include
import org.jetbrains.compose.web.attributes.AttrsBuilder import org.jetbrains.compose.web.attributes.AttrsScope
import org.jetbrains.compose.web.dom.* import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.dom.Text import org.jetbrains.compose.web.dom.Text
import org.w3c.dom.* import org.w3c.dom.*
@@ -15,9 +15,9 @@ fun <T> DefaultTable(
vararg tableModifiers: UIKitModifier, vararg tableModifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLTableElement> = {}, attributesCustomizer: AttrBuilderContext<HTMLTableElement> = {},
headerCustomizer: AttrBuilderContext<HTMLTableSectionElement> = {}, headerCustomizer: AttrBuilderContext<HTMLTableSectionElement> = {},
headerCellCustomizer: AttrsBuilder<HTMLTableCellElement>.(i: Int) -> Unit = {}, headerCellCustomizer: AttrsScope<HTMLTableCellElement>.(i: Int) -> Unit = {},
rowAttributes: AttrsBuilder<HTMLTableRowElement>.(t: T) -> Unit = {}, rowAttributes: AttrsScope<HTMLTableRowElement>.(t: T) -> Unit = {},
cellCustomizer: AttrsBuilder<HTMLTableCellElement>.(i: Int, t: T) -> Unit = { _, _ -> }, cellCustomizer: AttrsScope<HTMLTableCellElement>.(i: Int, t: T) -> Unit = { _, _ -> },
betweenHeaderAndBodyFiller: ContentBuilder<HTMLTableElement> = {}, betweenHeaderAndBodyFiller: ContentBuilder<HTMLTableElement> = {},
cellFiller: @Composable ElementScope<HTMLTableCellElement>.(i: Int, t: T) -> Unit cellFiller: @Composable ElementScope<HTMLTableCellElement>.(i: Int, t: T) -> Unit
) { ) {
@@ -72,14 +72,14 @@ fun <T> DefaultTable(
vararg tableModifiers: UIKitModifier, vararg tableModifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLTableElement> = {}, attributesCustomizer: AttrBuilderContext<HTMLTableElement> = {},
headerCustomizer: AttrBuilderContext<HTMLTableSectionElement> = {}, headerCustomizer: AttrBuilderContext<HTMLTableSectionElement> = {},
headerCellCustomizer: AttrsBuilder<HTMLTableCellElement>.(i: Int, title: String) -> Unit = { _, _ -> }, headerCellCustomizer: AttrsScope<HTMLTableCellElement>.(i: Int, title: String) -> Unit = { _, _ -> },
rowAttributes: AttrsBuilder<HTMLTableRowElement>.(t: T) -> Unit = {}, rowAttributes: AttrsScope<HTMLTableRowElement>.(t: T) -> Unit = {},
cellCustomizer: AttrsBuilder<HTMLTableCellElement>.(i: Int, t: T) -> Unit = { _, _ -> }, cellCustomizer: AttrsScope<HTMLTableCellElement>.(i: Int, t: T) -> Unit = { _, _ -> },
betweenHeaderAndBodyFiller: ContentBuilder<HTMLTableElement> = {}, betweenHeaderAndBodyFiller: ContentBuilder<HTMLTableElement> = {},
cellFiller: @Composable ElementScope<HTMLTableCellElement>.(i: Int, t: T) -> Unit cellFiller: @Composable ElementScope<HTMLTableCellElement>.(i: Int, t: T) -> Unit
) { ) {
val headersByIndex = heading.mapIndexed { index, s -> index to s }.toMap() val headersByIndex = heading.mapIndexed { index, s -> index to s }.toMap()
val headerCellCustomizer: AttrsBuilder<HTMLTableCellElement>.(i: Int) -> Unit = { i -> val headerCellCustomizer: AttrsScope<HTMLTableCellElement>.(i: Int) -> Unit = { i ->
val header = headersByIndex[i] val header = headersByIndex[i]
if (header != null) { if (header != null) {
headerCellCustomizer(i, header) headerCellCustomizer(i, header)

View File

@@ -0,0 +1,21 @@
package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.UIKitTile
import dev.inmo.jsuikit.modifiers.include
import dev.inmo.jsuikit.utils.Attrs
import org.jetbrains.compose.web.dom.ContentBuilder
import org.jetbrains.compose.web.dom.Div
import org.w3c.dom.HTMLDivElement
@Composable
fun Tile(
attrs: Attrs<HTMLDivElement> = Attrs.empty(),
contentBuilder: ContentBuilder<HTMLDivElement>
) = Div(
{
include(UIKitTile)
attrs.builder(this)
},
contentBuilder
)

View File

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

View File

@@ -1,6 +1,7 @@
package dev.inmo.jsuikit.modifiers package dev.inmo.jsuikit.modifiers
import dev.inmo.jsuikit.utils.* import dev.inmo.jsuikit.utils.Milliseconds
import dev.inmo.jsuikit.utils.buildAttribute
import org.w3c.dom.PageTransitionEvent import org.w3c.dom.PageTransitionEvent
sealed class UIKitAccordion( sealed class UIKitAccordion(

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

@@ -0,0 +1,17 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitClose(
override val classes: Array<String> = emptyArray(),
override val otherAttrs: Map<String, String> = emptyMap()
) : UIKitModifier {
object Large : UIKitClose(
arrayOf("uk-close-large")
)
companion object : UIKitClose(
arrayOf("uk-close"),
mapOf("uk-close" to "")
)
}

View File

@@ -0,0 +1,19 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitContainer(
override val classes: Array<String> = emptyArray(),
override val otherAttrs: Map<String, String> = emptyMap()
) : UIKitModifier {
sealed class Size(size: String) : UIKitContainer(arrayOf("uk-container-$size")) {
object XSmall : Size("xsmall")
object Small : Size("small")
object Large : Size("large")
object XLarge : Size("xlarge")
object Expand : Size("expand")
}
companion object : UIKitContainer(
arrayOf("uk-container")
)
}

View File

@@ -0,0 +1,11 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitDescriptionList(
override val classes: Array<String>
) : UIKitModifier {
object Divider : UIKitDescriptionList(arrayOf("uk-description-list-divider"))
companion object : UIKitDescriptionList(arrayOf("uk-description-list"))
}

View File

@@ -1,5 +1,9 @@
package dev.inmo.jsuikit.modifiers 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 { sealed class UIKitDropdown(classname: String) : UIKitModifier {
override val classes: Array<String> = arrayOf(classname) override val classes: Array<String> = arrayOf(classname)
@@ -50,6 +54,9 @@ sealed class UIKitDropdown(classname: String) : UIKitModifier {
object Click : Mode("click") object Click : Mode("click")
object Hover : Mode("hover") object Hover : Mode("hover")
object None : Mode("")
object HoverAndClick : Mode("$Hover, $Click")
} }
sealed class Flip(name: String) : AttributeValue(name) { 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

@@ -47,8 +47,9 @@ sealed class UIKitForm(
object Icon : UIKitForm("uk-form-icon") object Icon : UIKitForm("uk-form-icon")
class Custom( class Custom(
target: String = "true" target: String? = null
) : UIKitForm( ) : UIKitForm(
"uk-form-custom",
otherAttrs = mapOf( otherAttrs = mapOf(
buildAttribute("uk-form-custom") { buildAttribute("uk-form-custom") {
"target" to target "target" to target

View File

@@ -1,7 +1,6 @@
package dev.inmo.jsuikit.modifiers package dev.inmo.jsuikit.modifiers
import dev.inmo.jsuikit.utils.* import dev.inmo.jsuikit.utils.*
import org.jetbrains.compose.web.css.CSSKeyframe
sealed class UIKitHeight( sealed class UIKitHeight(
classname: String?, classname: String?,

View File

@@ -0,0 +1,8 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitInverse(classname: String) : UIKitModifier {
override val classes: Array<String> = arrayOf(classname)
object Light : UIKitInverse("uk-light")
object Dark : UIKitInverse("uk-dark")
}

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 package dev.inmo.jsuikit.modifiers
import org.jetbrains.compose.web.attributes.AttrsBuilder 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 { interface UIKitModifier {
val classes: Array<String> val classes: Array<String>
@@ -9,9 +12,22 @@ interface UIKitModifier {
get() = emptyMap() get() = emptyMap()
} }
fun AttrsBuilder<*>.include(vararg container: UIKitModifier?) { fun AttrsScope<*>.include(vararg container: UIKitModifier?) {
container.forEach { container.forEach {
it ?.classes ?.let { newClasses -> classes(*newClasses) } it ?.classes ?.let { newClasses -> classes(*newClasses) }
it ?.otherAttrs ?.let { attrs -> attrs.forEach { (k, v) -> attr(k, v) } } 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

@@ -0,0 +1,16 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitOverlay(
override val classes: Array<String> = emptyArray(),
override val otherAttrs: Map<String, String> = emptyMap()
) : UIKitModifier {
object Default : UIKitOverlay(arrayOf("uk-overlay-default"))
object Primary : UIKitOverlay(arrayOf("uk-overlay-primary"))
object Icon : UIKitOverlay(arrayOf("uk-overlay-icon"))
companion object : UIKitOverlay(
arrayOf("uk-overlay")
)
}

View File

@@ -8,7 +8,10 @@ sealed class UIKitPadding(suffix: String?) : UIKitModifier {
object Small : Size("small") object Small : Size("small")
object Large : Size("large") 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,5 @@
package dev.inmo.jsuikit.modifiers
object UIKitPlaceholder : UIKitModifier {
override val classes: Array<String> = arrayOf("uk-placeholder")
}

View File

@@ -20,3 +20,12 @@ sealed class UIKitScreenSizeModifier(val name: String) {
} }
fun UIKitModifier.applyWhenScreenSizeIs(size: UIKitScreenSizeModifier) = size.modify(this) fun UIKitModifier.applyWhenScreenSizeIs(size: UIKitScreenSizeModifier) = size.modify(this)
val UIKitModifier.onSmallScreens
get() = applyWhenScreenSizeIs(UIKitScreenSizeModifier.Small)
val UIKitModifier.onMediumScreens
get() = applyWhenScreenSizeIs(UIKitScreenSizeModifier.Medium)
val UIKitModifier.onLargeScreens
get() = applyWhenScreenSizeIs(UIKitScreenSizeModifier.Large)
val UIKitModifier.onXLargeScreens
get() = applyWhenScreenSizeIs(UIKitScreenSizeModifier.XLarge)

View File

@@ -0,0 +1,15 @@
package dev.inmo.jsuikit.modifiers
sealed class UIKitTile(
override val classes: Array<String> = emptyArray(),
override val otherAttrs: Map<String, String> = emptyMap()
) : UIKitModifier {
object Default : UIKitTile(arrayOf("uk-tile-default"))
object Muted : UIKitTile(arrayOf("uk-tile-muted"))
object Primary : UIKitTile(arrayOf("uk-tile-primary"))
object Secondary : UIKitTile(arrayOf("uk-tile-secondary"))
companion object : UIKitTile(arrayOf("uk-tile"))
}

View File

@@ -111,4 +111,5 @@ sealed class UIKitUtility(classname: String) : UIKitModifier {
object Active : UIKitUtility("uk-active") object Active : UIKitUtility("uk-active")
object Open : UIKitUtility("uk-open") object Open : UIKitUtility("uk-open")
object Link : UIKitUtility("uk-link")
} }

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(element: Element): UIKitDialog
fun modal(selector: String): 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,8 +2,6 @@ package dev.inmo.jsuikit.types
import dev.inmo.jsuikit.modifiers.UIKit import dev.inmo.jsuikit.modifiers.UIKit
import dev.inmo.jsuikit.utils.Milliseconds import dev.inmo.jsuikit.utils.Milliseconds
import org.w3c.dom.Element
import kotlin.js.Json
import kotlin.js.json import kotlin.js.json
typealias NotificationsGroup = String typealias NotificationsGroup = String

View File

@@ -2,26 +2,24 @@ package dev.inmo.jsuikit.utils
class AttributeBuilder ( class AttributeBuilder (
val attributeName: String, val attributeName: String,
val skipNullValues: Boolean = true, val parametersBuilder: ParametersBuilder
private val parametersPreset: MutableMap<String, String?> = mutableMapOf()
) { ) {
fun build(): Pair<String, String> = parametersBuilder.build().run {
fun add(k: String, v: Any? = null) { Pair(
if (v != null || !skipNullValues) { attributeName, toList().joinToString(";") {
parametersPreset[k] = v ?.toString() "${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, attributeName,
skipNullValues ParametersBuilder(skipNullValues)
).apply(block).build() ).apply {
parametersBuilder.block()
}.build()

View File

@@ -2,20 +2,21 @@ package dev.inmo.jsuikit.utils
import dev.inmo.jsuikit.modifiers.UIKitModifier import dev.inmo.jsuikit.modifiers.UIKitModifier
import dev.inmo.jsuikit.modifiers.include import dev.inmo.jsuikit.modifiers.include
import org.jetbrains.compose.web.attributes.AttrsBuilder import org.jetbrains.compose.web.attributes.AttrsScope
import org.jetbrains.compose.web.dom.AttrBuilderContext import org.jetbrains.compose.web.attributes.builders.InputAttrsScope
import org.w3c.dom.Element import org.w3c.dom.Element
import org.w3c.dom.HTMLInputElement
class AttributesCollection<T : Element> ( class AttributesCollection<T : Element, Builder : AttrsScope<T>> (
private vararg val modifiers: UIKitModifier, private vararg val modifiers: UIKitModifier?,
private val attrs: AttrBuilderContext<T> = {} private val attrs: Builder.() -> Unit = {}
) { ) {
val builder: AttrBuilderContext<T> = { val builder: Builder.() -> Unit = {
include(*modifiers) include(*modifiers)
attrs() attrs()
} }
operator fun plus(other: AttributesCollection<T>) = AttributesCollection<T>( operator fun plus(other: AttributesCollection<T, Builder>) = AttributesCollection<T, Builder>(
*(modifiers + other.modifiers).distinct().toTypedArray() *(modifiers + other.modifiers).distinct().toTypedArray()
) { ) {
this@AttributesCollection.attrs.invoke(this) this@AttributesCollection.attrs.invoke(this)
@@ -26,8 +27,9 @@ class AttributesCollection<T : Element> (
val Empty = Attrs<Element>() val Empty = Attrs<Element>()
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun <T : Element> empty() = Empty as Attrs<T> fun <T : Element, Builder : AttrsScope<T>> empty() = Empty as AttributesCollection<T, Builder>
} }
} }
typealias Attrs<T> = AttributesCollection<T> typealias Attrs<T> = AttributesCollection<T, AttrsScope<T>>
typealias InputAttrs<T> = AttributesCollection<HTMLInputElement, InputAttrsScope<T>>

View File

@@ -0,0 +1,55 @@
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()