diff --git a/.gitignore b/.gitignore index 53f4850d..69680178 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,9 @@ # .idea/*.iml # .idea/modules +.idea/caches +.idea/artifacts + # CMake cmake-build-*/ diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 00000000..f12b9b9e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 00000000..3e12dca4 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/kotlinScripting.xml b/.idea/kotlinScripting.xml new file mode 100644 index 00000000..bc444dea --- /dev/null +++ b/.idea/kotlinScripting.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 00000000..8b7f4afd --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 90952968..3c85ccc7 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -6,6 +6,12 @@ + + + + + @@ -32,7 +38,7 @@ - + \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..089dadfd --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 subroh_0508 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 8e47e4e2..39a8fd5e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,25 @@ # kotlin-material-ui Kotlin Wrapper Library of Material-UI + +Core: [ ![Download](https://api.bintray.com/packages/subroh0508/maven/Kotlin-Material-UI/images/download.svg) ](https://bintray.com/subroh0508/maven/Kotlin-Material-UI/_latestVersion) + +Lab: [ ![Download](https://api.bintray.com/packages/subroh0508/maven/Kotlin-Material-UI-Lab/images/download.svg) ](https://bintray.com/subroh0508/maven/Kotlin-Material-UI-Lab/_latestVersion) + +## Installation + +``` +repositories { + jcenter() + // or maven { url 'https://dl.bintray.com/subroh0508/maven' } +} + +dependencies { + implementation "net.subroh0508.kotlinmaterialui:core:${version}" + implementation "net.subroh0508.kotlinmaterialui:lab:${version}" +} +``` + +## License + +This project is licensed under the terms of the +[MIT license](/LICENSE). diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 632facec..00000000 --- a/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -plugins { - id 'kotlin2js' version '1.3.11' - id 'org.jetbrains.kotlin.jvm' version '1.3.11' -} - -group 'subroh0508.net' -version '1.0-SNAPSHOT' - -repositories { - mavenCentral() -} - -dependencies { - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8" - compile "org.jetbrains.kotlin:kotlin-stdlib-js" - testCompile "org.jetbrains.kotlin:kotlin-test-js" -} - -compileKotlin { - kotlinOptions.jvmTarget = "1.8" -} -compileTestKotlin { - kotlinOptions.jvmTarget = "1.8" -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..e912c995 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,60 @@ +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile +import org.jetbrains.kotlin.gradle.plugin.KotlinJsPluginWrapper +import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension + +group = Packages.group +version = "1.0-SNAPSHOT" + +plugins { + kotlin("js") apply false +} + +internal val Task.jsOutputDir: File + get() = project.rootProject.buildDir + .resolve("js/packages/${project.name}/kotlin") + +internal val Task.jsOutputFileName: String + get() = "${project.name}.js" + +val Task.jsOutputFile: String + get() = jsOutputDir.resolve(jsOutputFileName).absolutePath + +subprojects { + repositories { + google() + jcenter() + mavenCentral() + maven(url = "https://dl.bintray.com/kotlin/kotlin-eap") + maven(url = "http://dl.bintray.com/kotlin/kotlinx.html") + maven(url = "http://dl.bintray.com/kotlin/kotlin-js-wrappers") + } + + if (project.name != "sample") { + jsPlugin() + } +} + +fun Project.jsPlugin() { + plugins.withType { + extensions.configure { + js(BOTH) { + browser() + } + + tasks.withType().configureEach { + kotlinOptions { + moduleKind = "commonjs" + + if (name == "compileKotlinJs") { + outputFile = jsOutputFile + sourceMapEmbedSources = "always" + sourceMap = true + } else { + sourceMap = false + } + } + } + } + } +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 00000000..7cf6e0a1 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + `kotlin-dsl` +} + +repositories { + gradlePluginPortal() +} + +dependencies { + implementation(kotlin("gradle-plugin", "1.4.30")) + implementation("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5") +} diff --git a/buildSrc/src/main/java/Libraries.kt b/buildSrc/src/main/java/Libraries.kt new file mode 100644 index 00000000..e1e8e048 --- /dev/null +++ b/buildSrc/src/main/java/Libraries.kt @@ -0,0 +1,50 @@ +@Suppress("unused") +object Libraries { + object Plugin { + const val kotlinGradle = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Kotlin.version}" + } + + const val bintray = "1.8.5" + + object Kotlin { + const val version = "1.4.30" + const val wrappersBuild = "pre.148-kotlin-$version" + + const val js = "org.jetbrains.kotlin:kotlin-stdlib-js:$version" + const val jsTest = "org.jetbrains.kotlin:kotlin-test-js:$version" + + const val reactVersion = "${Npm.react}-$wrappersBuild" + const val react = "org.jetbrains:kotlin-react:$reactVersion" + const val reactDom = "org.jetbrains:kotlin-react-dom:$reactVersion" + + const val htmlVersion = "0.7.1" + const val html = "org.jetbrains.kotlinx:kotlinx-html-js:$htmlVersion" + + const val cssVersion = "1.0.0-$wrappersBuild" + const val css = "org.jetbrains:kotlin-css-js:$cssVersion" + + const val styledVersion = "${Npm.styledComponent}-$wrappersBuild" + const val styled = "org.jetbrains:kotlin-styled:$styledVersion" + + const val extensionsVersion = "1.0.1-$wrappersBuild" + const val extensions = "org.jetbrains:kotlin-extensions:$extensionsVersion" + } + + object Npm { + const val styledComponent = "5.2.1" + const val inlineStyledPrefixer = "^5.1.2" + const val react = "17.0.1" + + const val dateIo = "^2.6.0" + const val dateFns = "^2.12.0" + const val dayjs = "^1.8.16" + const val luxon = "^1.24.1" + const val moment = "^2.25.3" + + object MaterialUi { + const val core = "4.11.3" + const val lab = "4.0.0-alpha.57" + const val pickers = "4.0.0-alpha.7" + } + } +} diff --git a/buildSrc/src/main/java/Packages.kt b/buildSrc/src/main/java/Packages.kt new file mode 100644 index 00000000..edd07628 --- /dev/null +++ b/buildSrc/src/main/java/Packages.kt @@ -0,0 +1,4 @@ +object Packages { + const val group = "net.subroh0508.kotlinmaterialui" + const val version = "0.5.5" +} diff --git a/buildSrc/src/main/java/bintray-metadata.gradle.kts b/buildSrc/src/main/java/bintray-metadata.gradle.kts new file mode 100644 index 00000000..fcebbd8d --- /dev/null +++ b/buildSrc/src/main/java/bintray-metadata.gradle.kts @@ -0,0 +1,21 @@ +import org.gradle.api.Project +import org.gradle.api.publish.PublicationArtifact +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.publish.maven.internal.artifact.FileBasedMavenArtifact +import java.io.File + +tasks.named("bintrayUpload") { + doFirst { + project.extensions + .getByName("publishing") + .publications.withType() + .all { artifact(project.moduleArtifact(name)) } + } +} + +fun Project.moduleArtifact(publicationName: String): PublicationArtifact = + ModuleArtifact(buildDir.resolve("publications/$publicationName/module.json")) + +class ModuleArtifact(moduleFile: File) : FileBasedMavenArtifact(moduleFile) { + override fun getDefaultExtension() = "module" +} diff --git a/buildSrc/src/main/java/maven-publishing.gradle.kts b/buildSrc/src/main/java/maven-publishing.gradle.kts new file mode 100644 index 00000000..28a31071 --- /dev/null +++ b/buildSrc/src/main/java/maven-publishing.gradle.kts @@ -0,0 +1,82 @@ +import groovy.util.Node +import java.text.SimpleDateFormat +import java.util.* + +plugins { + id("com.jfrog.bintray") + `maven-publish` + id("bintray-metadata") +} + +val group = "net.subroh0508.kotlinmaterialui" +val libVersion = "0.5.5" + +val siteUrl = "https://github.com/subroh0508/kotlin-material-ui" +val githubUrl = "https://github.com/subroh0508/kotlin-material-ui" + +val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZ") + +bintray { + user = project.findProperty("bintray_user")?.toString() + key = project.findProperty("bintray_key")?.toString() + setPublications("ToMavenPublication") + + publish = false + + val repoNameSuffix = when (project.name) { + "lab" -> "-Lab" + "pickers" -> "-Pickers" + "date-io" -> "-DateIO" + "date-fns" -> "-DateIO-date-fns" + else -> "" + } + pkg.run { + repo = "maven" + name = "Kotlin-Material-UI$repoNameSuffix" + setLicenses("Apache-2.0") + websiteUrl = siteUrl + vcsUrl = "$githubUrl.git" + issueTrackerUrl = "$githubUrl/issues" + publicDownloadNumbers = true + version.name = libVersion + version.released = dateFormat.format(Date()) + } +} + +publishing.publications { + create("ToMavenPublication") { + from(components["kotlin"]) + artifact(tasks.getByName("jsLegacySourcesJar")) + groupId = group + artifactId = project.name + version = libVersion + pom.withXml { + asNode().also { root -> + root.appendNode("description", "Kotlin Wrapper Library of Material-UI") + root.appendNode("name", "Kotlin-Material-UI${if (project.name == "core") "" else "/Lab"}") + root.appendNode("url", githubUrl) + root.appendPomConfig() + } + } + } +} + +fun Node.appendPomConfig() { + Node(this, "licenses").also { licenses -> + Node(licenses, "license").also { license -> + license.appendNode("name", "The MIT Licenses") + license.appendNode("url", "https://opensource.org/licenses/MIT") + license.appendNode("distribution", "repo") + } + } + Node(this, "developers").also { developers -> + Node(developers, "developer").also { developer -> + developer.appendNode("id", "subroh0508") + developer.appendNode("name", "Subroh Nishikori") + developer.appendNode("email", "in-the-n@me-of.love") + } + } + Node(this, "scm").also { scm -> + scm.appendNode("url", githubUrl) + } +} diff --git a/core/.gitignore b/core/.gitignore new file mode 100644 index 00000000..d1638636 --- /dev/null +++ b/core/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/core/build.gradle.kts b/core/build.gradle.kts new file mode 100644 index 00000000..de782279 --- /dev/null +++ b/core/build.gradle.kts @@ -0,0 +1,19 @@ +group = Packages.group +version = Packages.version + +plugins { + kotlin("js") + id("maven-publishing") +} + +dependencies { + api(Libraries.Kotlin.html) + api(Libraries.Kotlin.react) + api(Libraries.Kotlin.reactDom) + api(Libraries.Kotlin.css) + api(Libraries.Kotlin.extensions) + + api(npm("@material-ui/core", Libraries.Npm.MaterialUi.core)) + + testImplementation(Libraries.Kotlin.jsTest) +} diff --git a/core/src/main/kotlin/materialui/aliases.kt b/core/src/main/kotlin/materialui/aliases.kt new file mode 100644 index 00000000..c94cb584 --- /dev/null +++ b/core/src/main/kotlin/materialui/aliases.kt @@ -0,0 +1,7 @@ +package materialui + +import react.RClass +import react.RProps + +internal typealias MakeStyles = (RProps) -> dynamic +internal typealias WithStyles = (Any) -> RClass diff --git a/core/src/main/kotlin/materialui/components/MaterialElementBuilder.kt b/core/src/main/kotlin/materialui/components/MaterialElementBuilder.kt new file mode 100644 index 00000000..983634a5 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/MaterialElementBuilder.kt @@ -0,0 +1,63 @@ +package materialui.components + +import kotlinext.js.Object +import kotlinext.js.jsObject +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import react.RClass +import react.ReactElement +import react.createElement +import react.dom.RDOMBuilder + +abstract class MaterialElementBuilder( + val type: RClass, + classMap: List, String>>, + factory: (TagConsumer) -> T +) : RDOMBuilder(factory) { + protected val materialProps: Props = jsObject { } + + fun props(p: Props) { Object.assign(materialProps, p) } + + fun Tag.classes(rootStyle: String) { + classes(listOf(MaterialStyle.root to rootStyle)) + } + + fun Tag.classes(vararg classMap: Pair, String>) { + classes(classMap.map { (key, value) -> key.toString() to value }) + } + + fun Tag.classes(classMap: List, String>>) { + classes(classMap.map { (key, value) -> key.toString() to value }) + } + + fun Tag.classes(vararg classMap: Pair) { + classes(classMap.map { (key, value) -> key to value }) + } + + fun Tag.classes(classMap: List>) { + if (classMap.isEmpty()) { + return + } + + val classesObj: dynamic = jsObject { } + + classMap.forEach { (key, value) -> classesObj[key] = value } + + classes = classesObj as Any + } + + var Tag.classes: Any? by materialProps + var Tag.className: String? by materialProps + var Tag.component: Any? by materialProps + + init { + attrs.classes(classMap) + attrs.component = attrs.tagName + } + + override fun create(): ReactElement { + Object.keys(materialProps).forEach { key -> setProp(key, materialProps[key]) } + + return createElement(type, props, *childList.toTypedArray()) + } +} diff --git a/core/src/main/kotlin/materialui/components/MaterialElementStyles.kt b/core/src/main/kotlin/materialui/components/MaterialElementStyles.kt new file mode 100644 index 00000000..ff2f2972 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/MaterialElementStyles.kt @@ -0,0 +1,5 @@ +package materialui.components + +import kotlinx.css.CSSBuilder + +typealias MaterialElementStyles = Map diff --git a/core/src/main/kotlin/materialui/components/MaterialStyle.kt b/core/src/main/kotlin/materialui/components/MaterialStyle.kt new file mode 100644 index 00000000..0d85cc75 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/MaterialStyle.kt @@ -0,0 +1,6 @@ +package materialui.components + +@Suppress("EnumEntryName") +internal enum class MaterialStyle { + root +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/StandardProps.kt b/core/src/main/kotlin/materialui/components/StandardProps.kt new file mode 100644 index 00000000..0d9c9099 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/StandardProps.kt @@ -0,0 +1,53 @@ +package materialui.components + +import kotlinx.css.StyledElement +import materialui.reacttransiton.RTransitionGroupProps +import react.dom.DOMProps +import kotlin.reflect.KProperty + +external interface StandardProps : DOMProps { + var classes: dynamic + var component: dynamic +} + +operator fun StandardProps.get(key: String): Any? = asDynamic()[key] + +inline operator fun > StandardProps.get(key: String): E?{ + val value = asDynamic()[key] + return when (value) { + null -> null + undefined -> null + else -> enumValueOf(value.toString()) + } +} + +inline operator fun > StandardProps.set(key: String,value: E?) { + asDynamic()[key] = when (value) { + null -> undefined + else -> value.toString() + } +} + +operator fun StandardProps.getValue(thisRef: Any?, property: KProperty<*>): dynamic + = asDynamic()[property.name] + +operator fun StandardProps.setValue(thisRef: Any?, property: KProperty<*>, value: dynamic) { + asDynamic()[property.name] = value +} + +//issue:problem with type argument ?> its not bounds enumValueOf +inline operator fun > StandardProps.getValue(thisRef: Any?, property: KProperty<*>): T?{ + val value = asDynamic()[property.name] + return when (value) { + null -> null + undefined -> null + else -> enumValueOf(value.toString()) + } +} + +inline operator fun > StandardProps.setValue(thisRef: Any?, property: KProperty<*>, value: T?) { + asDynamic()[property.name] = when (value) { + null -> undefined + else -> value.toString() + } +} diff --git a/core/src/main/kotlin/materialui/components/appbar/AppBarElementBuilder.kt b/core/src/main/kotlin/materialui/components/appbar/AppBarElementBuilder.kt new file mode 100644 index 00000000..022c90c5 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/appbar/AppBarElementBuilder.kt @@ -0,0 +1,24 @@ +package materialui.components.appbar + +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import materialui.components.appbar.enums.AppBarColor +import materialui.components.appbar.enums.AppBarPosition +import materialui.components.appbar.enums.AppBarStyle +import materialui.components.getValue +import materialui.components.paper.PaperElementBuilder +import materialui.components.setValue +import react.RClass + +class AppBarElementBuilder internal constructor( + type: RClass, + classMap: List, String>>, + factory: (TagConsumer) -> T +) : PaperElementBuilder(type, classMap, factory) { + fun Tag.classes(vararg classMap: Pair) { + classes(classMap.map { it.first to it.second }) + } + + var Tag.color: AppBarColor? by materialProps + var Tag.position: AppBarPosition? by materialProps +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/appbar/appBar.kt b/core/src/main/kotlin/materialui/components/appbar/appBar.kt new file mode 100644 index 00000000..f6527789 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/appbar/appBar.kt @@ -0,0 +1,20 @@ +package materialui.components.appbar + +import kotlinx.html.DIV +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import materialui.AppBar +import materialui.components.appbar.enums.AppBarStyle +import materialui.components.paper.PaperProps +import react.RBuilder + +external interface AppBarProps : PaperProps { + var color: String? + var position: String? +} + +fun RBuilder.appBar(vararg classMap: Pair, block: AppBarElementBuilder
.() -> Unit) + = child(AppBarElementBuilder(AppBar, classMap.toList()) { DIV(mapOf(), it) }.apply(block).create()) + +fun RBuilder.appBar(vararg classMap: Pair, factory: (TagConsumer) -> T, block: AppBarElementBuilder.() -> Unit) + = child(AppBarElementBuilder(AppBar, classMap.toList(), factory).apply(block).create()) diff --git a/core/src/main/kotlin/materialui/components/appbar/enums/AppBarColor.kt b/core/src/main/kotlin/materialui/components/appbar/enums/AppBarColor.kt new file mode 100644 index 00000000..f3df6e41 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/appbar/enums/AppBarColor.kt @@ -0,0 +1,6 @@ +package materialui.components.appbar.enums + +@Suppress("EnumEntryName") +enum class AppBarColor { + inherit, primary, secondary, default +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/appbar/enums/AppBarPosition.kt b/core/src/main/kotlin/materialui/components/appbar/enums/AppBarPosition.kt new file mode 100644 index 00000000..662e2ef3 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/appbar/enums/AppBarPosition.kt @@ -0,0 +1,6 @@ +package materialui.components.appbar.enums + +@Suppress("EnumEntryName") +enum class AppBarPosition { + fixed, absolute, sticky, static, relative +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/appbar/enums/AppBarStyle.kt b/core/src/main/kotlin/materialui/components/appbar/enums/AppBarStyle.kt new file mode 100644 index 00000000..ea369161 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/appbar/enums/AppBarStyle.kt @@ -0,0 +1,14 @@ +package materialui.components.appbar.enums + +@Suppress("EnumEntryName") +enum class AppBarStyle { + root, + positionFixed, + positionAbsolute, + positionSticky, + positionStatic, + positionRelative, + colorDefault, + colorPrimary, + colorSecondary +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/avatar/AvatarElementBuilder.kt b/core/src/main/kotlin/materialui/components/avatar/AvatarElementBuilder.kt new file mode 100644 index 00000000..f50eca89 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/avatar/AvatarElementBuilder.kt @@ -0,0 +1,41 @@ +package materialui.components.avatar + +import kotlinext.js.js +import kotlinx.html.IMG +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import kotlinx.html.stream.createHTML +import materialui.components.MaterialElementBuilder +import materialui.components.avatar.enum.AvatarStyle +import materialui.components.getValue +import materialui.components.setValue +import react.RClass +import react.RProps + +class AvatarElementBuilder internal constructor( + type: RClass, + classMap: List, String>>, + factory: (TagConsumer) -> T +) : MaterialElementBuilder(type, classMap, factory) { + fun Tag.classes(vararg classMap: Pair) { + classes(classMap.map { it.first to it.second }) + } + + var Tag.imgProps: RProps? by materialProps + var Tag.alt: String? by materialProps + var Tag.childrenClassName: String? by materialProps + var Tag.sizes: String? by materialProps + var Tag.src: String? by materialProps + var Tag.srcSet: String? by materialProps + + fun Tag.imgProps(block: IMG.() -> Unit) { + val props = js { } + + IMG(mapOf(), createHTML()).apply(block).attributesEntries.forEach { (key, value) -> + props[key] = value + } + + @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") + imgProps = props as RProps + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/avatar/avatar.kt b/core/src/main/kotlin/materialui/components/avatar/avatar.kt new file mode 100644 index 00000000..3231accb --- /dev/null +++ b/core/src/main/kotlin/materialui/components/avatar/avatar.kt @@ -0,0 +1,25 @@ +package materialui.components.avatar + +import kotlinx.html.DIV +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import materialui.Avatar +import materialui.components.StandardProps +import materialui.components.avatar.enum.AvatarStyle +import react.RBuilder +import react.RProps + +external interface AvatarProps : StandardProps { + var imgProps: RProps? + var alt: String? + var childrenClassName: String? + var sizes: String? + var src: String? + var srcSet: String? +} + +fun RBuilder.avatar(vararg classMap: Pair, block: AvatarElementBuilder
.() -> Unit) + = child(AvatarElementBuilder(Avatar, classMap.toList()) { DIV(mapOf(), it) }.apply(block).create()) + +fun RBuilder.avatar(vararg classMap: Pair, factory: (TagConsumer) -> T, block: AvatarElementBuilder.() -> Unit) + = child(AvatarElementBuilder(Avatar, classMap.toList(), factory).apply(block).create()) diff --git a/core/src/main/kotlin/materialui/components/avatar/enum/AvatarStyle.kt b/core/src/main/kotlin/materialui/components/avatar/enum/AvatarStyle.kt new file mode 100644 index 00000000..12b01be0 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/avatar/enum/AvatarStyle.kt @@ -0,0 +1,8 @@ +package materialui.components.avatar.enum + +@Suppress("EnumEntryName") +enum class AvatarStyle { + root, + colorDefault, + img +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/backdrop/BackdropElementBuilder.kt b/core/src/main/kotlin/materialui/components/backdrop/BackdropElementBuilder.kt new file mode 100644 index 00000000..936134ca --- /dev/null +++ b/core/src/main/kotlin/materialui/components/backdrop/BackdropElementBuilder.kt @@ -0,0 +1,43 @@ +package materialui.components.backdrop + +import kotlinext.js.js +import kotlinext.js.jsObject +import materialui.components.backdrop.enum.BackdropStyle +import materialui.reacttransiton.RTransitionBuilder +import react.RClass + +class BackdropElementBuilder internal constructor( + type: RClass, + classMap: List> +) : RTransitionBuilder(type, jsObject { }){ + init { + props.classes(classMap) + } + + fun BackdropProps.classes(vararg classMap: Pair, String>) { + classes(classMap.map { (key, value) -> key to value }) + } + + fun BackdropProps.classes(classMap: List, String>>) { + classes(classMap.map { (key, value) -> key.toString() to value }) + } + + fun BackdropProps.classes(vararg classMap: Pair) { + classes(classMap.map { (key, value) -> key to value }) + } + + fun BackdropProps.classes(classMap: List>) { + if (classMap.isEmpty()) { + return + } + + val classesObj: dynamic = jsObject { } + + classMap.forEach { (key, value) -> classesObj[key] = value } + + asDynamic()["classes"] = classesObj as Any + } + + fun BackdropProps.transitionDuration(msec: Long) { transitionDuration = msec } + fun BackdropProps.transitionDuration(enter: Long?, start: Long?) { transitionDuration = js { this["enter"] = enter; this["start"] } } +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/backdrop/backdrop.kt b/core/src/main/kotlin/materialui/components/backdrop/backdrop.kt new file mode 100644 index 00000000..37f59d15 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/backdrop/backdrop.kt @@ -0,0 +1,16 @@ +package materialui.components.backdrop + +import materialui.Backdrop +import materialui.components.backdrop.enum.BackdropStyle +import materialui.components.fade.FadeProps +import react.RBuilder + +external interface BackdropProps : FadeProps { + var classes: Any? + var invisible: Boolean? + var open: Boolean? + var transitionDuration: dynamic +} + +fun RBuilder.backdrop(vararg classMap: Pair, block: BackdropElementBuilder.() -> Unit) + = child(BackdropElementBuilder(Backdrop, classMap.toList()).apply(block).create()) diff --git a/core/src/main/kotlin/materialui/components/backdrop/enum/BackdropStyle.kt b/core/src/main/kotlin/materialui/components/backdrop/enum/BackdropStyle.kt new file mode 100644 index 00000000..517d4fe7 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/backdrop/enum/BackdropStyle.kt @@ -0,0 +1,7 @@ +package materialui.components.backdrop.enum + +@Suppress("EnumEntryName") +enum class BackdropStyle { + root, + invisible +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/badge/BadgeElementBuilder.kt b/core/src/main/kotlin/materialui/components/badge/BadgeElementBuilder.kt new file mode 100644 index 00000000..2a992d5c --- /dev/null +++ b/core/src/main/kotlin/materialui/components/badge/BadgeElementBuilder.kt @@ -0,0 +1,33 @@ +package materialui.components.badge + +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import materialui.components.MaterialElementBuilder +import materialui.components.badge.enums.BadgeColor +import materialui.components.badge.enums.BadgeStyle +import materialui.components.badge.enums.BadgeVariant +import materialui.components.getValue +import materialui.components.setValue +import react.RBuilder +import react.RClass +import react.ReactElement +import react.buildElement + +class BadgeElementBuilder internal constructor( + type: RClass, + classMap: List, String>>, + factory: (TagConsumer) -> T +) : MaterialElementBuilder(type, classMap, factory) { + fun Tag.classes(vararg classMap: Pair) { + classes(classMap.map { it.first to it.second }) + } + + var Tag.badgeContent: ReactElement? by materialProps + var Tag.color: BadgeColor? by materialProps + var Tag.invisible: Boolean? by materialProps + var Tag.max: Number? by materialProps + var Tag.showZero: Boolean? by materialProps + var Tag.variant: BadgeVariant? by materialProps + + fun Tag.badgeContent(block: RBuilder.() -> Unit) { badgeContent = buildElement(block) } +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/badge/badge.kt b/core/src/main/kotlin/materialui/components/badge/badge.kt new file mode 100644 index 00000000..2183a671 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/badge/badge.kt @@ -0,0 +1,27 @@ +package materialui.components.badge + +import kotlinx.html.SPAN +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import materialui.Badge +import materialui.components.StandardProps +import materialui.components.badge.enums.BadgeColor +import materialui.components.badge.enums.BadgeStyle +import materialui.components.badge.enums.BadgeVariant +import react.RBuilder +import react.ReactElement + +external interface BadgeProps : StandardProps { + var badgeContent: ReactElement? + var color: BadgeColor? + var invisible: Boolean? + var max: Number? + var showZero: Boolean? + var variant: BadgeVariant? +} + +fun RBuilder.badge(vararg classMap: Pair, block: BadgeElementBuilder.() -> Unit) + = child(BadgeElementBuilder(Badge, classMap.toList()) { SPAN(mapOf(), it) }.apply(block).create()) + +fun RBuilder.badge(vararg classMap: Pair, factory: (TagConsumer) -> T, block: BadgeElementBuilder.() -> Unit) + = child(BadgeElementBuilder(Badge, classMap.toList(), factory).apply(block).create()) diff --git a/core/src/main/kotlin/materialui/components/badge/enums/BadgeColor.kt b/core/src/main/kotlin/materialui/components/badge/enums/BadgeColor.kt new file mode 100644 index 00000000..5453afd3 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/badge/enums/BadgeColor.kt @@ -0,0 +1,6 @@ +package materialui.components.badge.enums + +@Suppress("EnumEntryName") +enum class BadgeColor { + default, primary, secondary, error +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/badge/enums/BadgeStyle.kt b/core/src/main/kotlin/materialui/components/badge/enums/BadgeStyle.kt new file mode 100644 index 00000000..7730eed8 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/badge/enums/BadgeStyle.kt @@ -0,0 +1,12 @@ +package materialui.components.badge.enums + +@Suppress("EnumEntryName") +enum class BadgeStyle { + root, + badge, + colorPrimary, + colorSecondary, + colorError, + invisible, + dot +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/badge/enums/BadgeVariant.kt b/core/src/main/kotlin/materialui/components/badge/enums/BadgeVariant.kt new file mode 100644 index 00000000..4f6c2ffb --- /dev/null +++ b/core/src/main/kotlin/materialui/components/badge/enums/BadgeVariant.kt @@ -0,0 +1,6 @@ +package materialui.components.badge.enums + +@Suppress("EnumEntryName") +enum class BadgeVariant { + standard, dot +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/bottomnavigation/BottomNavigationElementBuilder.kt b/core/src/main/kotlin/materialui/components/bottomnavigation/BottomNavigationElementBuilder.kt new file mode 100644 index 00000000..f278f864 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/bottomnavigation/BottomNavigationElementBuilder.kt @@ -0,0 +1,17 @@ +package materialui.components.bottomnavigation + +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import materialui.components.MaterialElementBuilder +import materialui.components.getValue +import materialui.components.setValue +import react.RClass + +class BottomNavigationElementBuilder internal constructor( + type: RClass, + classMap: List, String>>, + factory: (TagConsumer) -> T +) : MaterialElementBuilder(type, classMap, factory) { + var Tag.showLabels: Boolean? by materialProps + var Tag.value: Any? by materialProps +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/bottomnavigation/bottomNavigation.kt b/core/src/main/kotlin/materialui/components/bottomnavigation/bottomNavigation.kt new file mode 100644 index 00000000..8faa1cd7 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/bottomnavigation/bottomNavigation.kt @@ -0,0 +1,20 @@ +package materialui.components.bottomnavigation + +import kotlinx.html.DIV +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import materialui.BottomNavigation +import materialui.components.MaterialStyle +import materialui.components.StandardProps +import react.RBuilder + +external interface BottomNavigationProps : StandardProps { + var showLabels: Boolean? + var value: Any? +} + +fun RBuilder.bottomNavigation(rootStyle: String? = null, block: BottomNavigationElementBuilder
.() -> Unit) + = child(BottomNavigationElementBuilder(BottomNavigation, listOfNotNull(rootStyle?.let { MaterialStyle.root to it })) { DIV(mapOf(), it) }.apply(block).create()) + +fun RBuilder.bottomNavigation(rootStyle: String? = null, factory: (TagConsumer) -> T, block: BottomNavigationElementBuilder.() -> Unit) + = child(BottomNavigationElementBuilder(BottomNavigation, listOfNotNull(rootStyle?.let { MaterialStyle.root to it }), factory).apply(block).create()) diff --git a/core/src/main/kotlin/materialui/components/bottomnavigationaction/BottomNavigationActionElementBuilder.kt b/core/src/main/kotlin/materialui/components/bottomnavigationaction/BottomNavigationActionElementBuilder.kt new file mode 100644 index 00000000..f98fe727 --- /dev/null +++ b/core/src/main/kotlin/materialui/components/bottomnavigationaction/BottomNavigationActionElementBuilder.kt @@ -0,0 +1,28 @@ +package materialui.components.bottomnavigationaction + +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import materialui.components.buttonbase.ButtonBaseElementBuilder +import materialui.components.buttonbase.enums.ButtonBaseStyle +import materialui.components.getValue +import materialui.components.setValue +import react.RBuilder +import react.RClass +import react.ReactElement +import react.buildElement + +class BottomNavigationActionElementBuilder internal constructor( + type: RClass, + classMap: List>, + factory: (TagConsumer) -> T +) : ButtonBaseElementBuilder(type, classMap, factory) { + + var Tag.icon: ReactElement? by materialProps + var Tag.label: ReactElement? by materialProps + var Tag.selected: Boolean? by materialProps + var Tag.showLabel: Boolean? by materialProps + var Tag.value: Any? by materialProps + + fun Tag.icon(block: RBuilder.() -> Unit) { icon = buildElement(block) } + fun Tag.label(block: RBuilder.() -> Unit) { label = buildElement(block) } +} \ No newline at end of file diff --git a/core/src/main/kotlin/materialui/components/bottomnavigationaction/bottomNavigationAction.kt b/core/src/main/kotlin/materialui/components/bottomnavigationaction/bottomNavigationAction.kt new file mode 100644 index 00000000..5056febf --- /dev/null +++ b/core/src/main/kotlin/materialui/components/bottomnavigationaction/bottomNavigationAction.kt @@ -0,0 +1,24 @@ +package materialui.components.bottomnavigationaction + +import kotlinx.html.BUTTON +import kotlinx.html.Tag +import kotlinx.html.TagConsumer +import materialui.BottomNavigationAction +import materialui.components.buttonbase.ButtonBaseProps +import materialui.components.buttonbase.enums.ButtonBaseStyle +import react.RBuilder +import react.ReactElement + +external interface BottomNavigationActionProps : ButtonBaseProps { + var icon: ReactElement? + var label: ReactElement? + var selected: Boolean? + var showLabel: Boolean? + var value: Any? +} + +fun RBuilder.bottomNavigationAction(vararg classMap: Pair, block: BottomNavigationActionElementBuilder