好的,我现在已经开始工作了,其中包括几个步骤。
- 安装 npm 依赖项
kotlin {
...
sourceSets {
val jsMain by getting {
dependencies {
// dependencies for Compose for Web
implementation(compose.web.core)
implementation(compose.runtime)
// dependencies for Clarity Design System
implementation(npm("@cds/core", "5.6.0"))
implementation(npm("@cds/city", "1.1.0"))
// dependency for webpack - see step 3
implementation(npm("file-loader", "6.2.0"))
}
}
...
}
}
- 启用 css 支持
这似乎是必需的,以便包含全局样式表。
kotlin {
js(IR) {
browser {
...
commonWebpackConfig {
cssSupport.enabled = true
}
}
...
}
...
}
- 添加对
.woff2
Clarity
样式表中包含的文件的支持 CDS 的样式表包含 type 的字体文件,.woff2
必须配置其在 webpack 中的支持。这可以通过webpack.config.d/support-fonts.js
在项目根目录创建具有以下内容的文件来实现:
config.module.rules.push({
test: /\.(woff(2)?|ttf|eot|svg|gif|png|jpe?g)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}]
});
- 包括全局样式表
external fun require(module: String): dynamic
fun main() {
require("modern-normalize/modern-normalize.css")
require("@cds/core/global.min.css")
require("@cds/core/styles/module.shims.min.css")
require("@cds/city/css/bundles/default.min.css")
...
}
- 导入
register.js
所需的 Web 组件
external fun require(module: String): dynamic
fun main() {
...
require("@cds/core/button/register.js")
...
}
- 为 Web 组件创建 @Composable
遗憾的是,此解决方案使用标记为 的 API @OptIn(ComposeWebInternalApi::class)
,它代表“此 API 是内部的,将来可能会更改”。任何关于如何在不依赖内部 API 的情况下实现这一点的提示都值得赞赏。
@Composable
fun CdsButton(
status: CdsButtonStatus = CdsButtonStatus.Primary,
attrs: AttrBuilderContext<HTMLElement>? = null,
content: ContentBuilder<HTMLElement>? = null
) = TagElement(
elementBuilder = CdsElementBuilder("cds-button"),
applyAttrs = {
if (attrs != null) apply(attrs)
attr("status", status.attributeValue)
},
content = content
)
/**
* This is a copy of the private class org.jetbrains.compose.web.dom.ElementBuilderImplementation
*/
internal class CdsElementBuilder<TElement : Element>(private val tagName: String) : ElementBuilder<TElement> {
private val element: Element by lazy {
document.createElement(tagName)
}
override fun create(): TElement = element.cloneNode() as TElement
}
sealed interface CdsButtonStatus {
object Primary : CdsButtonStatus
...
}
internal val CdsButtonStatus.attributeValue
get() = when (this) {
CdsButtonStatus.Primary -> "primary"
...
}
- 让我们成为你的
@Composable
!
fun main() {
...
renderComposable(rootElementId = "root") {
CdsButton(
status = CdsButtonStatus.Success
) {
Text("It works! :-)")
}
}
}