rgossiaux / svelte-headlessui

Unofficial Svelte port of the Headless UI component library
https://svelte-headlessui.goss.io
MIT License
1.78k stars 94 forks source link

Scoped global styling not working #110

Open pikeas opened 2 years ago

pikeas commented 2 years ago

Describe the bug Scoped global styling doesn't seem to work. Classes are being applied and the component is reactive, so the issue is specifically around style scoping.

To Reproduce

<script lang="ts">
    import MyComponent from "$lib/things/MyComponent.svelte"
</script>

<section>
    <MyComponent />
</section>

MyComponent is exactly copied from https://svelte-headlessui.goss.io/docs/general-concepts#the-global-modifier, the version using a wrapper div and * > :global(.checked).

pikeas commented 2 years ago

I just sanity checked this with dummy components:

<script lang="ts">
    import Outer from "$lib/foo/Outer.svelte"
</script>

<Outer />
<script lang="ts">
    import Inner from "./Inner.svelte"
</script>

<div>Outer 1</div>
<div><Inner foo="inner" /></div>
<div>Outer 2</div>

<style>
    * > :global(.inner) {
        color: red;
    }
</style>
<script lang="ts">
    export let foo = ""
</script>

<div class={foo}>Inner</div>

This works as expected so svelte-headlessui is doing something funky. Maybe related to using class as the prop name?

pikeas commented 2 years ago

The plot thickens!

For RadioGroup:

For Dialog:

Ah, just found this docs note:

This rule won’t work properly inside a portal, which means that it won’t work properly for a \<Dialog>. To style the \<Dialog>, you will need to either 1) use global styles without the * > scoping, 2) put a wrapper element inside the \<Dialog> and style that instead, or 3) use one of the other styling approaches.

I think that explains everything I've seen. Definitely surprising!

I'll keep this open for the RadioGroup behavior - should this work with and without the descendant selector?