Compare commits

...

79 Commits

Author SHA1 Message Date
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
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
2a3f14593b use iterables for data in default tables 2022-03-01 13:26:04 +06:00
bfd6790014 start 0.0.40 2022-03-01 13:25:37 +06:00
27ad91be74 Merge pull request #40 from InsanusMokrassar/0.0.39
0.0.39
2022-03-01 01:21:19 +06:00
49 changed files with 857 additions and 133 deletions

View File

@@ -1,5 +1,82 @@
# Changelog
## 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
## 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
* All `DefaultTable` functions now use `Iterable` as data type
## 0.0.39
* Add support of `Notifications`

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.39
version=0.1.1

View File

@@ -1,9 +1,9 @@
[versions]
kt = "1.6.10"
jb-compose = "1.0.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.3.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -1,9 +1,8 @@
package dev.inmo.jsuikit
import dev.inmo.jsuikit.modifiers.AttributeValue
import dev.inmo.jsuikit.utils.AttributeBuilder
import dev.inmo.jsuikit.utils.buildAttribute
import org.jetbrains.compose.web.attributes.AttrsBuilder
import dev.inmo.jsuikit.utils.*
import org.jetbrains.compose.web.attributes.AttrsScope
@Deprecated("Will be removed soon")
class UIKitAttributeValueBuilder {
@@ -22,10 +21,10 @@ class UIKitAttributeValueBuilder {
fun build(): String = attrs.joinToString(";") { (k, v) -> "$k: $v" }
}
fun AttrsBuilder<*>.buildAndAddAttribute(
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

@@ -4,7 +4,7 @@ import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.modifiers.UIKitAccordion
import dev.inmo.jsuikit.modifiers.include
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.w3c.dom.*
@@ -12,7 +12,7 @@ import org.w3c.dom.*
fun <T> Accordion(
data: Iterable<T>,
attrs: Attrs<HTMLUListElement> = Attrs.empty(),
itemAttrsBuilder: AttrsBuilder<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
itemAttrsBuilder: AttrsScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
itemContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit
) {
Ul(
@@ -33,13 +33,13 @@ fun <T> Accordion(
fun <T> DefaultAccordion(
data: Iterable<T>,
attrs: Attrs<HTMLUListElement> = Attrs.empty(),
itemAttrsBuilder: AttrsBuilder<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
titleAttrsBuilder: AttrsBuilder<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
itemAttrsBuilder: AttrsScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
titleAttrsBuilder: AttrsScope<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
titleContentBuilder: @Composable ElementScope<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
beforeTitleContentBuilder: @Composable ElementScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
afterTitleContentBuilder: @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
) = Accordion(
data,
@@ -72,9 +72,9 @@ fun <T> DefaultAccordion(
data: Iterable<T>,
titleResolver: (Int, T) -> String,
attrs: Attrs<HTMLUListElement> = Attrs.empty(),
itemAttrsBuilder: AttrsBuilder<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
titleAttrsBuilder: AttrsBuilder<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
contentAttrsBuilder: AttrsBuilder<HTMLDivElement>.(Int, T) -> Unit = { _, _ -> },
itemAttrsBuilder: AttrsScope<HTMLLIElement>.(Int, T) -> Unit = { _, _ -> },
titleAttrsBuilder: AttrsScope<HTMLAnchorElement>.(Int, T) -> Unit = { _, _ -> },
contentAttrsBuilder: AttrsScope<HTMLDivElement>.(Int, T) -> Unit = { _, _ -> },
contentContentBuilder: @Composable ElementScope<HTMLDivElement>.(Int, T) -> Unit
) = DefaultAccordion(
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.utils.Attrs
import org.jetbrains.compose.web.dom.*
import org.w3c.dom.*
import org.w3c.dom.HTMLDivElement
import org.w3c.dom.HTMLHeadingElement
@Composable
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 dev.inmo.jsuikit.modifiers.*
import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.dom.Text
import org.w3c.dom.*
import org.w3c.dom.HTMLDivElement
import org.w3c.dom.HTMLElement
import org.w3c.dom.events.Event
import kotlin.random.Random
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 dev.inmo.jsuikit.buildAndAddAttribute
import dev.inmo.jsuikit.modifiers.*
import dev.inmo.jsuikit.types.DropdownOptions
import dev.inmo.jsuikit.utils.Milliseconds
import dev.inmo.jsuikit.utils.buildAttribute
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,
@@ -27,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

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

View File

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

View File

@@ -1,9 +1,11 @@
package dev.inmo.jsuikit.elements
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 org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.dom.Span
import org.jetbrains.compose.web.dom.Text
import org.w3c.dom.HTMLSpanElement
@Composable

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,8 +93,8 @@ fun SubNav(
@Composable
fun <T> Nav(
title: String,
data: SnapshotStateList<T>,
title: String?,
data: Iterable<T>,
vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(),
multiple: Boolean? = null,
@@ -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,8 +136,8 @@ fun <T> Nav(
@Composable
fun <T> DefaultNav(
title: String,
data: SnapshotStateList<T>,
title: String?,
data: Iterable<T>,
vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(),
multiple: Boolean? = null,
@@ -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,14 +160,15 @@ fun <T> DefaultNav(
duration,
besidesTitleAndList,
titleCustomizer,
afterTitleContentBuilder,
ulCustomizer,
elementAllocator
)
@Composable
fun <T> PrimaryNav(
title: String,
data: SnapshotStateList<T>,
title: String?,
data: Iterable<T>,
vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(),
multiple: Boolean? = null,
@@ -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,14 +191,15 @@ fun <T> PrimaryNav(
duration,
besidesTitleAndList,
titleCustomizer,
afterTitleContentBuilder,
ulCustomizer,
elementAllocator
)
@Composable
fun <T> SubNav(
title: String,
data: SnapshotStateList<T>,
title: String?,
data: Iterable<T>,
vararg ulModifiers: UIKitModifier,
titleModifiers: Array<UIKitModifier> = emptyArray(),
multiple: Boolean? = null,
@@ -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

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

View File

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

View File

@@ -1,9 +1,9 @@
package dev.inmo.jsuikit.elements
import androidx.compose.runtime.Composable
import androidx.compose.runtime.snapshots.SnapshotStateList
import dev.inmo.jsuikit.modifiers.*
import org.jetbrains.compose.web.attributes.AttrsBuilder
import dev.inmo.jsuikit.modifiers.UIKitModifier
import dev.inmo.jsuikit.modifiers.include
import org.jetbrains.compose.web.attributes.AttrsScope
import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.dom.Text
import org.w3c.dom.*
@@ -11,13 +11,13 @@ import org.w3c.dom.*
@Composable
fun <T> DefaultTable(
headerBuilders: List<ContentBuilder<HTMLTableCellElement>>,
dataList: SnapshotStateList<T>,
dataList: Iterable<T>,
vararg tableModifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLTableElement> = {},
headerCustomizer: AttrBuilderContext<HTMLTableSectionElement> = {},
headerCellCustomizer: AttrsBuilder<HTMLTableCellElement>.(i: Int) -> Unit = {},
rowAttributes: AttrsBuilder<HTMLTableRowElement>.(t: T) -> Unit = {},
cellCustomizer: AttrsBuilder<HTMLTableCellElement>.(i: Int, t: T) -> Unit = { _, _ -> },
headerCellCustomizer: AttrsScope<HTMLTableCellElement>.(i: Int) -> Unit = {},
rowAttributes: AttrsScope<HTMLTableRowElement>.(t: T) -> Unit = {},
cellCustomizer: AttrsScope<HTMLTableCellElement>.(i: Int, t: T) -> Unit = { _, _ -> },
betweenHeaderAndBodyFiller: ContentBuilder<HTMLTableElement> = {},
cellFiller: @Composable ElementScope<HTMLTableCellElement>.(i: Int, t: T) -> Unit
) {
@@ -68,18 +68,18 @@ fun <T> DefaultTable(
@Composable
fun <T> DefaultTable(
heading: List<String>,
dataList: SnapshotStateList<T>,
dataList: Iterable<T>,
vararg tableModifiers: UIKitModifier,
attributesCustomizer: AttrBuilderContext<HTMLTableElement> = {},
headerCustomizer: AttrBuilderContext<HTMLTableSectionElement> = {},
headerCellCustomizer: AttrsBuilder<HTMLTableCellElement>.(i: Int, title: String) -> Unit = { _, _ -> },
rowAttributes: AttrsBuilder<HTMLTableRowElement>.(t: T) -> Unit = {},
cellCustomizer: AttrsBuilder<HTMLTableCellElement>.(i: Int, t: T) -> Unit = { _, _ -> },
headerCellCustomizer: AttrsScope<HTMLTableCellElement>.(i: Int, title: String) -> Unit = { _, _ -> },
rowAttributes: AttrsScope<HTMLTableRowElement>.(t: T) -> Unit = {},
cellCustomizer: AttrsScope<HTMLTableCellElement>.(i: Int, t: T) -> Unit = { _, _ -> },
betweenHeaderAndBodyFiller: ContentBuilder<HTMLTableElement> = {},
cellFiller: @Composable ElementScope<HTMLTableCellElement>.(i: Int, t: T) -> Unit
) {
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]
if (header != null) {
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
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
import dev.inmo.jsuikit.utils.*
import dev.inmo.jsuikit.utils.Milliseconds
import dev.inmo.jsuikit.utils.buildAttribute
import org.w3c.dom.PageTransitionEvent
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
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

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

View File

@@ -1,7 +1,6 @@
package dev.inmo.jsuikit.modifiers
import dev.inmo.jsuikit.utils.*
import org.jetbrains.compose.web.css.CSSKeyframe
sealed class UIKitHeight(
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
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 {
val classes: Array<String>
@@ -9,9 +12,22 @@ interface UIKitModifier {
get() = emptyMap()
}
fun AttrsBuilder<*>.include(vararg container: UIKitModifier?) {
fun AttrsScope<*>.include(vararg container: UIKitModifier?) {
container.forEach {
it ?.classes ?.let { newClasses -> classes(*newClasses) }
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 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)
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 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(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.utils.Milliseconds
import org.w3c.dom.Element
import kotlin.js.Json
import kotlin.js.json
typealias NotificationsGroup = String

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

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