compose-multiplatform icon indicating copy to clipboard operation
compose-multiplatform copied to clipboard

LocalDensity not available in Web project.

Open xtexChooser opened this issue 1 year ago • 6 comments

IllegalStateException: CompositionLocal LocalDensity not present

This happens when Material 3 used with Web.

A minimal reproducer: untitled.zip

See hfhbd/routing-compose#204.

xtexChooser avatar Jul 13 '22 05:07 xtexChooser

You might need to add this if you get cli.isMultipleCompiler is not a function:

afterEvaluate {
    rootProject.extensions.configure<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension> {
        versions.webpackCli.version = "4.10.0"
    }
}

hfhbd avatar Jul 13 '22 06:07 hfhbd

You might need to add this if you get cli.isMultipleCompiler is not a function:

afterEvaluate {
    rootProject.extensions.configure<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension> {
        versions.webpackCli.version = "4.10.0"
    }
}

I think it may have been fixed in dev745.

xtexChooser avatar Jul 13 '22 07:07 xtexChooser

Material tested, the same error

xtexChooser avatar Jul 13 '22 07:07 xtexChooser

Nope, it needs to fixed in Kotlin Gradle Plugin for Js.

hfhbd avatar Jul 13 '22 07:07 hfhbd

Thanks.

xtexChooser avatar Jul 13 '22 07:07 xtexChooser

CompositionLocalProvider is missing too.

xtexChooser avatar Jul 13 '22 07:07 xtexChooser

Is there any solution to this issue , as even after using compose 1.4.0 and the above solutions including using web compose template, error is received but only when using material3 not material2 . It would be very useful if a solution is provided.Thank you

Deaths-Door avatar May 09 '23 20:05 Deaths-Door

This answer from darkmoon_u was an help for me. Wrapping with this will "fix" the issue but will make the code fail with this error Uncaught ReferenceError: org_jetbrains_skia_Paint__1nMake is not defined.

val fontFamilyResolver = createFontFamilyResolver()
CompositionLocalProvider(
    LocalDensity provides Density(1.0f),
    LocalLayoutDirection provides LayoutDirection.Ltr,
    LocalViewConfiguration provides DefaultViewConfiguration(Density(1.0f)),
    LocalInputModeManager provides InputModeManagerObject,
    LocalFontFamilyResolver provides fontFamilyResolver
) {
   // TODO
}

private object InputModeManagerObject : InputModeManager {
    override val inputMode = InputMode.Keyboard
    @ExperimentalComposeUiApi
    override fun requestInputMode(inputMode: InputMode) = false
}

But, my advice will be to give up with this approach but instead draw on html canvas with org.jetbrains.skiko.wasm. This will let you use oandroidx.compose.material.Text instead of org.jetbrains.compose.web.dom.Text and will be easier for you to share code across platforms.

With this answer and this sample, I managed to get my shared composable with Web, iOS, Android, Desktop "working" on version id("org.jetbrains.compose") version "1.4.0".

Here the dependencies to put:

sourceSets {
    sourceSets["jsMain"].dependencies {
        implementation(compose.runtime)
        implementation(compose.html.core)
        implementation(compose.ui)
        implementation(compose.foundation)
        implementation(compose.material)
        @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
        implementation(compose.components.resources)
    }
}

with

compose.experimental {
    web.application {}
}

and this html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Mercan</title>
    <script src="skiko.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>

<body>
<div>
    <canvas id="ComposeTarget" width="1600" height="950"></canvas>
</div>
<script src="<your_app_name.js"></script>
</body>

</html>

Thank you to this library maintainer 🙏, I hope I'm not missleading people.

Mercandj avatar May 13 '23 00:05 Mercandj

Thank you for your help , I will try and report back for anyone who may experience this issue in the future. I am using androidx.compose.material.Text instead of the org.jetbrains.compose.web.dom.Text , but why would the canvas method work , while

renderComposable(ROOT_ID){
 /*TODO*/
}

won' work. I have already tried

CompositionLocalProvider(
    LocalDensity provides Density(1.0f),
    LocalLayoutDirection provides LayoutDirection.Ltr) {}

it gave me the same issue.

But in general , isn't this a compose material3 issue as with material2 , this issue is not there , so is there any update that fixes this issue with material3 library

Deaths-Door avatar May 13 '23 20:05 Deaths-Door

I have tried it but how to set Content in canvas as onWasmReady gives error

Deaths-Door avatar May 14 '23 20:05 Deaths-Door