忘備録的な感じで残しておきます
なんかわかれば追加するかもです
↑実際に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
}