Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to toggle Dark Mode using $flux.dark or $flux.appearance #909

Open
3 tasks done
jpmorby opened this issue Dec 21, 2024 · 8 comments
Open
3 tasks done

Unable to toggle Dark Mode using $flux.dark or $flux.appearance #909

jpmorby opened this issue Dec 21, 2024 · 8 comments

Comments

@jpmorby
Copy link

jpmorby commented Dec 21, 2024

Flux version

v1.1.0

Livewire version

v3.5.17

What is the problem?

I've been trying to get the Dark Mode toggle to work on a project, and it just doesn't seem to want to do anything.

I've followed all the setup instructions and created a very basic test page .. but still nothing.

Code snippets

<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    @vite('resources/css/app.css')

    <link rel="preconnect" href="https://fonts.bunny.net">
    <link href="https://fonts.bunny.net/css?family=inter:400,500,600&display=swap" rel="stylesheet" />
    @fluxStyles
    @livewireStyles()
</head>

<body class="min-h-screen bg-white dark:bg-zinc-800">
    <flux:header container class="bg-zinc-50 dark:bg-zinc-900 border-b border-zinc-200 dark:border-zinc-700">

        <flux:button x-on:click="$flux.dark = ! $flux.dark" icon="moon">Toggle</flux:button>
    </flux:header>


    <flux:main container>
        <flux:heading size="xl" level="1">Flux Dark/Light mode toggle demo</flux:heading>

        <flux:subheading size="lg" class="mb-6">does it work?</flux:subheading>

        <flux:radio.group variant="segmented" x-model="$flux.appearance">
            <flux:radio value="light" icon="sun">Light</flux:radio>
            <flux:radio value="dark" icon="moon">Dark</flux:radio>
            <flux:radio value="system" icon="computer-desktop">System</flux:radio>
        </flux:radio.group>

        <flux:separator variant="subtle" />

    </flux:main>
    <flux:footer>
        <p class="text-center">Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }})</p>
    </flux:footer>


    @fluxScripts
    @livewireScripts()
</body>

</html>
import defaultTheme from 'tailwindcss/defaultTheme';

/** @type {import('tailwindcss').Config} */
export default {
    darkMode: 'selector',
    // darkMode: null,

    content: [
        './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
        './storage/framework/views/*.php',
        './resources/**/*.blade.php',
        './resources/**/*.js',
        './resources/**/*.vue',
        "./vendor/livewire/flux-pro/stubs/**/*.blade.php",
        "./vendor/livewire/flux/stubs/**/*.blade.php",

    ],
    theme: {
        extend: {
            fontFamily: {
                // sans: ['Figtree', ...defaultTheme.fontFamily.sans],
                sans: ['Inter', 'sans-serif'],

            },
        },
    },
    plugins: [],
};

How do you expect it to work?

press the toggle and see the colours change.

If I set darkMode: null then I see a colour change ... but not with it set to "selector" and the toggles

I did look for some sort of "users forum" / public support channel but couldn't find one otherwise I'd have posted this there first as I'm sure this is a "newbie" error more than a bug in the code.

I've also tried it with and without the @livewireScripts verbs ... no joy

Please confirm (incomplete submissions will not be addressed)

  • I have provided easy and step-by-step instructions to reproduce the bug.
  • I have provided code samples as text and NOT images.
  • I understand my bug report will be closed if I haven't met the criteria above.
@jeffchown
Copy link

@jpmorby Have you tried updating your @vite statement to:

@vite(['resources/css/app.css', 'resources/js/app.js'])

Then run npm run build, php artisan view:clear

@jpmorby
Copy link
Author

jpmorby commented Dec 21, 2024

Yes, sadly it makes no difference ...

The rendered HTML appears as so

<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="preload" as="style" href="https://fluxtest.test/build/assets/app-BgxMe6qT.css"/>
    <link rel="modulepreload" href="https://fluxtest.test/build/assets/app-Xaw6OIO1.js"/>
    <link rel="stylesheet" href="https://fluxtest.test/build/assets/app-BgxMe6qT.css" data-navigate-track="reload"/>
    <script type="module" src="https://fluxtest.test/build/assets/app-Xaw6OIO1.js" data-navigate-track="reload"></script>

    <link rel="preconnect" href="https://fonts.bunny.net">
    <link href="https://fonts.bunny.net/css?family=inter:400,500,600&display=swap" rel="stylesheet"/>
    <link rel="stylesheet" href="/flux/flux.css?id=da3247ce">
    <!-- Livewire Styles -->
    <style>
    [wire\:loading][wire\:loading], [wire\:loading\.delay][wire\:loading\.delay], [wire\:loading\.inline-block][wire\:loading\.inline-block], [wire\:loading\.inline][wire\:loading\.inline], [wire\:loading\.block][wire\:loading\.block], [wire\:loading\.flex][wire\:loading\.flex], [wire\:loading\.table][wire\:loading\.table], [wire\:loading\.grid][wire\:loading\.grid], [wire\:loading\.inline-flex][wire\:loading\.inline-flex] {
        display: none;
    }

    [wire\:loading\.delay\.none][wire\:loading\.delay\.none], [wire\:loading\.delay\.shortest][wire\:loading\.delay\.shortest], [wire\:loading\.delay\.shorter][wire\:loading\.delay\.shorter], [wire\:loading\.delay\.short][wire\:loading\.delay\.short], [wire\:loading\.delay\.default][wire\:loading\.delay\.default], [wire\:loading\.delay\.long][wire\:loading\.delay\.long], [wire\:loading\.delay\.longer][wire\:loading\.delay\.longer], [wire\:loading\.delay\.longest][wire\:loading\.delay\.longest] {
        display: none;
    }

    [wire\:offline][wire\:offline] {
        display: none;
    }

    [wire\:dirty]:not(textarea):not(input):not(select) {
        display: none;
    }

    :root {
        --livewire-progress-bar-color: #2299dd;
    }

    [x-cloak] {
        display: none !important;
    }
    </style>
</head>

<body class="min-h-screen bg-white dark:bg-zinc-800">

    <header class="[grid-area:header] z-10 min-h-14  bg-zinc-50 dark:bg-zinc-900 border-b border-zinc-200 dark:border-zinc-700" data-flux-header>
        <div class="mx-auto w-full h-full [:where(&)]:max-w-7xl px-6 lg:px-8 flex items-center">
            <button type="button" class="relative items-center font-medium justify-center gap-2 whitespace-nowrap disabled:opacity-75 dark:disabled:opacity-75 disabled:cursor-default disabled:pointer-events-none h-10 text-sm rounded-lg px-4 inline-flex  bg-white hover:bg-zinc-50 dark:bg-zinc-700 dark:hover:bg-zinc-600/75 text-zinc-800 dark:text-white border border-zinc-200 hover:border-zinc-200 border-b-zinc-300/80 dark:border-zinc-600 dark:hover:border-zinc-600 shadow-sm [[data-flux-button-group]_&amp;]:border-l-0 [:is([data-flux-button-group]&gt;&amp;:first-child,_[data-flux-button-group]_:first-child&gt;&amp;)]:border-l-[1px]" data-flux-button="data-flux-button" data-flux-group-target="data-flux-group-target" x-on:click="$flux.dark = ! $flux.dark">
                <svg class="shrink-0 [:where(&amp;)]:size-4" data-flux-icon xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" data-slot="icon">
                    <path d="M14.438 10.148c.19-.425-.321-.787-.748-.601A5.5 5.5 0 0 1 6.453 2.31c.186-.427-.176-.938-.6-.748a6.501 6.501 0 1 0 8.585 8.586Z"/>
                </svg>


                                
                                    Toggle
                    
            </button>
        </div>
    </header>

    <div class="[grid-area:main] p-6 lg:p-8 [[data-flux-container]_&amp;]:px-0 mx-auto w-full [:where(&amp;)]:max-w-7xl" data-flux-main>
        <h1 class="font-medium text-zinc-800 dark:text-white text-2xl [&amp;:has(+[data-flux-subheading])]:mb-2 [[data-flux-subheading]+&amp;]:mt-2" data-flux-heading>Flux Dark/Light mode toggle demo</h1>

        <div class="text-base text-zinc-500 dark:text-white/70 mb-6" data-flux-subheading>
            does it work?
        </div>

        <ui-radio-group class="block flex p-1 rounded-lg bg-zinc-800/5 dark:bg-white/10 h-10 p-1" x-model="$flux.appearance" data-flux-radio-group-segmented>
            <ui-radio class="flex whitespace-nowrap flex-1 justify-center items-center gap-2 rounded-md data-[checked]:shadow-sm text-sm font-medium text-zinc-600 hover:text-zinc-800 dark:hover:text-white dark:text-white/70 data-[checked]:text-zinc-800 data-[checked]:dark:text-white data-[checked]:bg-white data-[checked]:dark:bg-white/20 [&amp;[disabled]]:opacity-50 dark:[&amp;[disabled]]:opacity-75 [&amp;[disabled]]:cursor-default [&amp;[disabled]]:pointer-events-none px-4" value="light" data-flux-control data-flux-radio-segmented tabindex="-1">
                <svg class="shrink-0 [:where(&amp;)]:size-5 text-zinc-500 dark:text-zinc-400 [ui-radio[data-checked]_&]:text-zinc-800 dark:[ui-radio[data-checked]_&]:text-white" data-flux-icon xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon">
                    <path d="M10 2a.75.75 0 0 1 .75.75v1.5a.75.75 0 0 1-1.5 0v-1.5A.75.75 0 0 1 10 2ZM10 15a.75.75 0 0 1 .75.75v1.5a.75.75 0 0 1-1.5 0v-1.5A.75.75 0 0 1 10 15ZM10 7a3 3 0 1 0 0 6 3 3 0 0 0 0-6ZM15.657 5.404a.75.75 0 1 0-1.06-1.06l-1.061 1.06a.75.75 0 0 0 1.06 1.06l1.06-1.06ZM6.464 14.596a.75.75 0 1 0-1.06-1.06l-1.06 1.06a.75.75 0 0 0 1.06 1.06l1.06-1.06ZM18 10a.75.75 0 0 1-.75.75h-1.5a.75.75 0 0 1 0-1.5h1.5A.75.75 0 0 1 18 10ZM5 10a.75.75 0 0 1-.75.75h-1.5a.75.75 0 0 1 0-1.5h1.5A.75.75 0 0 1 5 10ZM14.596 15.657a.75.75 0 0 0 1.06-1.06l-1.06-1.061a.75.75 0 1 0-1.06 1.06l1.06 1.06ZM5.404 6.464a.75.75 0 0 0 1.06-1.06l-1.06-1.06a.75.75 0 1 0-1.061 1.06l1.06 1.06Z"/>
                </svg>


                            
                    Light

                    
            </ui-radio>
            <ui-radio class="flex whitespace-nowrap flex-1 justify-center items-center gap-2 rounded-md data-[checked]:shadow-sm text-sm font-medium text-zinc-600 hover:text-zinc-800 dark:hover:text-white dark:text-white/70 data-[checked]:text-zinc-800 data-[checked]:dark:text-white data-[checked]:bg-white data-[checked]:dark:bg-white/20 [&amp;[disabled]]:opacity-50 dark:[&amp;[disabled]]:opacity-75 [&amp;[disabled]]:cursor-default [&amp;[disabled]]:pointer-events-none px-4" value="dark" data-flux-control data-flux-radio-segmented tabindex="-1">
                <svg class="shrink-0 [:where(&amp;)]:size-5 text-zinc-500 dark:text-zinc-400 [ui-radio[data-checked]_&]:text-zinc-800 dark:[ui-radio[data-checked]_&]:text-white" data-flux-icon xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon">
                    <path fill-rule="evenodd" d="M7.455 2.004a.75.75 0 0 1 .26.77 7 7 0 0 0 9.958 7.967.75.75 0 0 1 1.067.853A8.5 8.5 0 1 1 6.647 1.921a.75.75 0 0 1 .808.083Z" clip-rule="evenodd"/>
                </svg>


                            
                    Dark

                    
            </ui-radio>
            <ui-radio class="flex whitespace-nowrap flex-1 justify-center items-center gap-2 rounded-md data-[checked]:shadow-sm text-sm font-medium text-zinc-600 hover:text-zinc-800 dark:hover:text-white dark:text-white/70 data-[checked]:text-zinc-800 data-[checked]:dark:text-white data-[checked]:bg-white data-[checked]:dark:bg-white/20 [&amp;[disabled]]:opacity-50 dark:[&amp;[disabled]]:opacity-75 [&amp;[disabled]]:cursor-default [&amp;[disabled]]:pointer-events-none px-4" value="system" data-flux-control data-flux-radio-segmented tabindex="-1">
                <svg class="shrink-0 [:where(&amp;)]:size-5 text-zinc-500 dark:text-zinc-400 [ui-radio[data-checked]_&]:text-zinc-800 dark:[ui-radio[data-checked]_&]:text-white" data-flux-icon xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon">
                    <path fill-rule="evenodd" d="M2 4.25A2.25 2.25 0 0 1 4.25 2h11.5A2.25 2.25 0 0 1 18 4.25v8.5A2.25 2.25 0 0 1 15.75 15h-3.105a3.501 3.501 0 0 0 1.1 1.677A.75.75 0 0 1 13.26 18H6.74a.75.75 0 0 1-.484-1.323A3.501 3.501 0 0 0 7.355 15H4.25A2.25 2.25 0 0 1 2 12.75v-8.5Zm1.5 0a.75.75 0 0 1 .75-.75h11.5a.75.75 0 0 1 .75.75v7.5a.75.75 0 0 1-.75.75H4.25a.75.75 0 0 1-.75-.75v-7.5Z" clip-rule="evenodd"/>
                </svg>


                            
                    System

                    
            </ui-radio>
        </ui-radio-group>

        <div data-orientation="horizontal" role="none" class="border-0 [print-color-adjust:exact] bg-zinc-800/5 dark:bg-white/10 h-px w-full" data-flux-separator></div>
    </div>
    <div class="[grid-area:footer] p-6 lg:p-8" data-flux-footer>
        <p class="text-center">Laravel v11.36.1 (PHP v8.4.1)</p>

    </div>

    <script src="/flux/flux.js?id=04a221f0" data-navigate-once></script>
    <!-- Livewire Scripts -->
    <script src="/livewire/livewire.js?id=02b08710" data-csrf="srbPupxLxouUdc3HS8ssC7sQ4xsr6McqnPv9fNPk" data-update-uri="/livewire/update" data-navigate-once="true"></script>
</body>

</html>

@jeffchown
Copy link

jeffchown commented Dec 21, 2024

@jpmorby I think you need to add an x-data to each of your flux:header and the flux:radio.group to 'activate' the Alpine code (x-on and x-model)

@jpmorby
Copy link
Author

jpmorby commented Dec 21, 2024

I’ll give that a try however it’s not mentioned anywhere in the docs. The example I’ve put together is literally a cut and paste of “working” objects from the online docs .. which indicate that you don’t need to do that sort of thing and flux does it all for you?

@jeffchown
Copy link

jeffchown commented Dec 21, 2024

@jpmorby You're right. It isn't mentioned but will probably be added at some point as this is coming up more frequently.

For example, this issue, #900 (comment), involves the same thing and snippets from the same area of the docs.

Flux can't know where you are placing the snippets from the docs and whether or not a parent element in your markup already contains an x-data, but it should be mentioned that there must be an x-data for such snippets to work properly.

@jpmorby
Copy link
Author

jpmorby commented Dec 21, 2024

Looks like we were both banging our heads at pretty much the same time then! :)

I've added x-data to the code snippets and it has indeed started working ... if flux can't do this directly then at least update the docs to show that it's needed?

I'm not a UI designer, I've always had a huge mental block when it comes to anything to do with UI design (I write back end systems and do IP networking / server maintenance) ... Flux and Tailwind have helped me get out of my comfort zone and start to do basic UI design (where as previously the interface might not have been much more than a TUI rather than a GUI ... and I can't be alone with those starting to make the jump) ..

Great work, keep it up!

@jeffchown
Copy link

jeffchown commented Dec 21, 2024

Glad that worked, @jpmorby

When I have some time, I'll submit a docs PR to @calebporzio @joshhanley re: the need for x-data with some snippets.

I hear you re UI. Flux and Tailwind CSS are great tools.
And, the more you work with Livewire and Alpine (via Flux), I think you'll find them to be very helpful as well.

Every project I do these days uses all of the above and this dev stack has greatly accelerated my work while allowing me to focus on each project's specific business needs (instead of getting caught in the UI & JS 'weeds').

@joshhanley
Copy link
Member

@jpmorby thanks for reporting! Yep @jeffchown is correct it needs the x-data. I've submitted a PR to the docs to add x-data to the dark mode examples, as it's one of the few components that are likely to be used outside of a Livewire component (which will set x-data` for you).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants