Skip to content

Commit

Permalink
MUI. Fix and unify all "classes" declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
aerialist7 committed May 4, 2024
1 parent de43332 commit 564be51
Show file tree
Hide file tree
Showing 307 changed files with 2,468 additions and 5,126 deletions.
113 changes: 50 additions & 63 deletions buildSrc/src/main/kotlin/karakum/mui/Converter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,82 +2,64 @@ package karakum.mui

import java.io.File

private const val JS_NAME_DEFAULT = "@JsName(\"default\")\n"

internal data class ConversionResult(
val main: String,
val extensions: String,
)

internal fun convertClasses(
componentName: String,
classesName: String,
definitionFile: File,
isBase: Boolean = false,
): Pair<String, String?> {
): String {
val content = definitionFile.readText()
.replace("\r\n", "\n")

val slots = mutableListOf<String>()
val comments = mutableListOf<String>()

val classesName = componentName + "Classes"
val muiName = MUI + componentName

val source = content.substringAfter("export interface $classesName {\n", "")

if (source.isEmpty()) {
check(componentName == "Container" || componentName == "Stack")
return "typealias $classesName = mui.system.$classesName" to "typealias $muiName = mui.system.$muiName"
check(classesName == "ContainerClasses" || classesName == "StackClasses")
return "external interface $classesName : mui.system.$classesName"
}

val classes = source
.substringBefore("\n}\n")
.trimIndent()
.splitToSequence("\n")
.map {
if (it.startsWith("/**"))
comments += it

val name = it.removeSuffix(": string;")
.removeSuffix("?")

if (name == it) return@map it
val classesInterface = getClassesContent(source)
val classesInterfaceContent = "external interface $classesName {\n$classesInterface}\n"

slots += name
val classesObject = getClassesContent(source, objectMode = true)
val classesObjectContent =
optionalJsNameDefaultAnnotation(content) +
"external object ${classesName.replaceFirstChar(Char::lowercase)} : $classesName {\n$classesObject}\n"

val line = "var $name: ClassName"
if (name.startsWith("'")) " // $line" else line
}
.joinToString("\n")

if (isBase) {
val classesContent = convertSealed(
name = classesName,
keys = slots,
comments = comments,
getValue = {
val name = if (it in MUI_COMMON_CLASS_MODIFIERS) "" else componentName
"base-$name-$it"
},
type = "ClassName",
)
return "$classesInterfaceContent\n$classesObjectContent"
}

return classesContent to null
private fun getClassesContent(
source: String,
objectMode: Boolean = false,
): String = source
.substringBefore("\n}\n")
.trimIndent()
.splitToSequence("\n")
.map {
if (objectMode && it.contains("*")) // skip comments in object mode only
return@map ""

val name = it.removeSuffix(": string;")
.removeSuffix("?")

if (name == it)
return@map "$it\n"

val line = if (objectMode)
"override var $name: ClassName = definedExternally"
else
"var $name: ClassName"

if (name.startsWith("'"))
" // $line\n"
else
"$line\n"
}

val classesContent = "external interface $classesName {\n" +
"$classes\n" +
"}\n"

val muiContent = convertSealed(
name = muiName,
keys = slots.filter { it !in MUI_COMMON_CLASS_MODIFIERS },
getValue = { "$muiName-$it" },
type = "ClassName",
)

return classesContent to muiContent
}
.joinToString("")

internal fun convertDefinitions(
definitionFile: File,
Expand Down Expand Up @@ -877,13 +859,18 @@ private fun findComponent(
else -> propsName
}

val jsNameAnnotation = if ("export default" in content || "export { default " in content) {
JS_NAME_DEFAULT
} else {
""
}
val jsNameDefault = optionalJsNameDefaultAnnotation(content)

return "$comment\n" +
jsNameAnnotation +
jsNameDefault +
"external val $name: react.$type<$typeParameter>"
}

private fun optionalJsNameDefaultAnnotation(
content: String,
): String =
if ("export default" in content || "export { default " in content) {
"@JsName(\"default\")\n"
} else {
""
}
15 changes: 5 additions & 10 deletions buildSrc/src/main/kotlin/karakum/mui/Generator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -701,20 +701,15 @@ private fun generate(
if (componentName == "RadioGroup")
return

val classesName = componentName + "Classes"
val classesFileName = "${componentName}Classes".replaceFirstChar(Char::lowercase)
val classesFile = definitionFile.parentFile.resolve("$classesFileName.d.ts")

@Suppress("DEPRECATION")
val classesFile = definitionFile.parentFile.resolve(classesName.decapitalize() + ".d.ts")
if (classesFile.exists()) {
val (classes, mui) = convertClasses(componentName, classesFile, isBase = pkg == Package.base)
val classes = convertClasses(classesFileName.replaceFirstChar(Char::uppercase), classesFile)
val annotation = moduleDeclaration(pkg, subpackage, componentName)

targetDir.resolve("$componentName.classes.kt")
.writeText(fileContent(body = classes, pkg = pkg))

if (mui != null) {
targetDir.resolve("$componentName.mui.kt")
.writeText(fileContent(body = mui, pkg = pkg))
}
.writeText(fileContent(annotations = annotation, body = classes, pkg = pkg))
}
}

Expand Down
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/karakum/mui/Mui.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ internal val MUI_COMMON_CLASS_MODIFIERS = listOf(
"selected",
)

// TODO: Looks redundant. Check
internal val MUI_BODY = convertSealed(
name = MUI,
keys = MUI_COMMON_CLASS_MODIFIERS,
Expand Down
30 changes: 1 addition & 29 deletions buildSrc/src/main/kotlin/karakum/mui/UnionConverter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,35 +68,7 @@ internal fun convertSealed(
type: String,
): String {
val companionContent = keys.asSequence()
.map {
if (!it.startsWith("'")) {
"@JsValue(\"${getValue(it)}\")\nval $it: $type"
} else {
""
}
}
.joinToString("\n")

return convertSealed(name, companionContent)
}

internal fun convertSealed(
name: String,
keys: List<String>,
comments: List<String>,
getValue: (String) -> String,
type: String,
): String {
require(keys.size == comments.size)

val companionContent = keys.asSequence()
.mapIndexed { index, it ->
if (!it.startsWith("'")) {
"${comments[index]}\n@JsValue(\"${getValue(it)}\")\nval $it: $type"
} else {
""
}
}
.map { "@JsValue(\"${getValue(it)}\")\nval $it: $type" }
.joinToString("\n")

return convertSealed(name, companionContent)
Expand Down
30 changes: 15 additions & 15 deletions mui-kotlin/src/jsMain/kotlin/mui/base/Badge.classes.kt
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
// Automatically generated - do not modify!

@file:JsModule("@mui/base/Badge")

package mui.base

import seskar.js.JsValue
import seskar.js.JsVirtual
import web.cssom.ClassName

@JsVirtual
sealed external interface BadgeClasses {
companion object {
/** Class name applied to the root element. */
@JsValue("base-Badge-root")
val root: ClassName
external interface BadgeClasses {
/** Class name applied to the root element. */
var root: ClassName

/** Class name applied to the badge `span` element. */
var badge: ClassName

/** Class name applied to the badge `span` element. */
@JsValue("base-Badge-badge")
val badge: ClassName
/** State class applied to the badge `span` element if `invisible={true}`. */
var invisible: ClassName
}

/** State class applied to the badge `span` element if `invisible={true}`. */
@JsValue("base-Badge-invisible")
val invisible: ClassName
}
external object badgeClasses : BadgeClasses {
override var root: ClassName = definedExternally
override var badge: ClassName = definedExternally
override var invisible: ClassName = definedExternally
}
42 changes: 21 additions & 21 deletions mui-kotlin/src/jsMain/kotlin/mui/base/Button.classes.kt
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
// Automatically generated - do not modify!

@file:JsModule("@mui/base/Button")

package mui.base

import seskar.js.JsValue
import seskar.js.JsVirtual
import web.cssom.ClassName

@JsVirtual
sealed external interface ButtonClasses {
companion object {
/** Class name applied to the root element. */
@JsValue("base-Button-root")
val root: ClassName

/** State class applied to the root `button` element if `active={true}`. */
@JsValue("base--active")
val active: ClassName

/** State class applied to the root `button` element if `disabled={true}`. */
@JsValue("base--disabled")
val disabled: ClassName

/** State class applied to the root `button` element if `focusVisible={true}`. */
@JsValue("base--focusVisible")
val focusVisible: ClassName
}
external interface ButtonClasses {
/** Class name applied to the root element. */
var root: ClassName

/** State class applied to the root `button` element if `active={true}`. */
var active: ClassName

/** State class applied to the root `button` element if `disabled={true}`. */
var disabled: ClassName

/** State class applied to the root `button` element if `focusVisible={true}`. */
var focusVisible: ClassName
}

external object buttonClasses : ButtonClasses {
override var root: ClassName = definedExternally
override var active: ClassName = definedExternally
override var disabled: ClassName = definedExternally
override var focusVisible: ClassName = definedExternally
}
58 changes: 29 additions & 29 deletions mui-kotlin/src/jsMain/kotlin/mui/base/FormControl.classes.kt
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
// Automatically generated - do not modify!

@file:JsModule("@mui/base/FormControl")

package mui.base

import seskar.js.JsValue
import seskar.js.JsVirtual
import web.cssom.ClassName

@JsVirtual
sealed external interface FormControlClasses {
companion object {
/** Class applied to the root element. */
@JsValue("base-FormControl-root")
val root: ClassName

/** State class applied to the root element if `disabled={true}`. */
@JsValue("base--disabled")
val disabled: ClassName

/** State class applied to the root element if `error={true}`. */
@JsValue("base--error")
val error: ClassName

/** State class applied to the root element if the inner input has value. */
@JsValue("base-FormControl-filled")
val filled: ClassName

/** State class applied to the root element if the inner input is focused. */
@JsValue("base--focused")
val focused: ClassName

/** State class applied to the root element if `required={true}`. */
@JsValue("base--required")
val required: ClassName
}
external interface FormControlClasses {
/** Class applied to the root element. */
var root: ClassName

/** State class applied to the root element if `disabled={true}`. */
var disabled: ClassName

/** State class applied to the root element if `error={true}`. */
var error: ClassName

/** State class applied to the root element if the inner input has value. */
var filled: ClassName

/** State class applied to the root element if the inner input is focused. */
var focused: ClassName

/** State class applied to the root element if `required={true}`. */
var required: ClassName
}

external object formControlClasses : FormControlClasses {
override var root: ClassName = definedExternally
override var disabled: ClassName = definedExternally
override var error: ClassName = definedExternally
override var filled: ClassName = definedExternally
override var focused: ClassName = definedExternally
override var required: ClassName = definedExternally
}
Loading

0 comments on commit 564be51

Please sign in to comment.