忘備録的な感じで残しておきます
なんかわかれば追加するかもです
↑実際にKotlin/JSで作成したポートフォリオのようなものです。
本記事はkotlin-wrappers 1.0.0-pre.545を対象として書かれています。
kotlin-wrappersはこれからの更新でも大量の破壊的変更が伴うことが予想されるため、バージョンが少しでも違う場合はこの記事を参考にしないほうがいい可能性があります。
[React Router] BrowserRouterが使えない!?
WebpackConfigでdevServer内のhistoryApiFallbackをtrueにする必要があるのですが、build.gradle.kts内のcommonWebpackConfigから変更することができないためwebpack.config.d/webpack.config.jsを作成し、
if (config.devServer){
//上書きしないようassign
config.devServer = Object.assign(config.devServer, {
historyApiFallback: true,
});
}
このように書きます。
[Emotion] styled('xxx')((...) => ...)←どう書くんや
MUIのAppBarのpositionをfixedにするときに困りました
const Offset = styled('div')(({ theme }) => theme.mixins.toolbar);
↓Kotlin/JSではこのように書きます
val Offset = div.styled {
+it.asDynamic().theme.unsafeCast<mui.material.styles.Theme>().mixins.toolbar.unsafeCast<Properties>()
}
+でProperties?.unaryPlus()を呼び出しています。
sealed class PropertiesBuilder :
Properties,
RuleBuilder<PropertiesBuilder>,
PseudosRuleBuilder<PropertiesBuilder> {
//↓おまえか!?!?!?
inline operator fun Properties?.unaryPlus() {
Object.assign(this@PropertiesBuilder, this)
}
}
キャストしないとIntelliJくんがProperties?.unaryPlus()出してくれないので罠ですこれ。
[React] PropsにReactNodeを渡したい!!!!
こんな感じでcreateをつけましょう
CardHeader {
title = Typography.create {
variant = TypographyVariant.h6
+it.name
}
}
前はcreateElement{}で囲むとできた
Node.jsをダウンロードしたくない!/ バージョンを変えたい!
build.gradle.ktsに追記しましょう
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin> {
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension>().run {
download = true // デフォルトの挙動 falseで既にインストールされているNode.jsを使う
nodeVersion = "16.15.0" // ここにNode.jsのバージョン
}
}
[MUI] <Grid xs={...}/>みたいなやつ
this.asDynamic()で無理やりできます。
Grid {
item = true
asDynamic().sm = 6
asDynamic().xs = 12
//...
}
asDynamic().component = "label"とかもできます。
対応するプロパティが見つからなかったら、断腸の思いでこれを使いましょう。
Kotlin/JSの意味・・・
npmパッケージの関数を自分でラップして使う
公式でも説明されていますが・・・
usehooks-tsの
を使ってみます。
npmの依存関係を書く
dependencies {
// ・・・
+ implementation(npm("usehooks-ts", "2.8.0"))
// ・・・
}
書く
src/main/kotlin/usehooksみたいなディレクトリを作ってそこに入れるような感じに私はしています。
今回使用するのはuseDarkModeなのでuseDarkMode.ktを作り、ここを見ながら書いていきます
@file:JsModule("usehooks-ts")
@file:JsNonModule
package usehooks
@JsName("useDarkMode")
external fun useDarkMode(defaultValue: Boolean? = definedExternally): UseDarkModeOutput
external interface UseDarkModeOutput {
val isDarkMode: Boolean
val toggle: () -> Unit
val enable: () -> Unit
val disable: () -> Unit
}
正解かはわかりませんがこのように書いたら動きました。
CSSとかのNoneが無い!!
あります。
web.cssom.None.Companion.none
です。
Auto.autoもあります。
Button{
css {
display=None.none
}
+"みえないボタン"
}
どのdocumentだよ!!!!!!
これはKotlin/JSあるあるですね。
安易にkotlin-wrappersのバージョンを上げるとパッケージ名が変わったりして時代に置いていかれます。
import react.create
import react.dom.client.createRoot
import web.dom.document
fun main() {
val container = document.createElement("div").also {
document.body.appendChild(it)
}
createRoot(container).render(
App.create()
)
}
このようなよく見るコードのdocumentですが、補完で2つのdocumentが出てきますよね。
web.dom.document
kotlinx.browser.document
これを間違えると、document.bodyがNullableになったり、createRootで型が違うと怒られます。
先程のコードの場合は上のweb.dom.documentが正解です。
下のkotlinx.browser.documentは使う場面あるんですかね・・?
どのwindowだよ!!!!!!
kotlinx-coroutinesのWindow.asCoroutineDispatcher()を使うときは、
kotlinx.browser.window.asCoroutineDispatcher()
です。
クラス Windowには以下の2種類あり、それぞれ別の場所からアクセスできます。
org.w3c.dom.Window //→ kotlinx.browser.window
web.window.Window //→ web.window.window
asCoroutineDispatcher()はorg.w3c.dom.Windowに対して使うのでkotlinx.browser.windowです。
[MUI] <Button component={Link}/> componentが無い!
足りないものは自分で作り出しましょう。
var ButtonProps.component : ElementType<*>?
get() = unsafeCast<PropsWithComponent>().component
set(value) { unsafeCast<PropsWithComponent>().component=value}
//例
Button{
component=Link
}