inertiajs / inertia

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.
https://inertiajs.com
MIT License
6.53k stars 434 forks source link

Cant use named slots in default layout set in createInertiaApp() #1470

Closed nezaboravi closed 1 year ago

nezaboravi commented 1 year ago

Version:

Describe the problem:

I cant use named slots. Here is the code from app.js AdminLayout.vue and Rules.vue I am getting error: [plugin:vite:vue] Codegen node is missing for element/if/for node. Apply appropriate transforms first.

image

Steps to reproduce:

app.js


import './bootstrap';
import '../css/app.css';

import { createApp, h } from 'vue';
import { createInertiaApp, Link, Head } from '@inertiajs/vue3';
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';
import AdminLayout from './Layouts/AdminLayout.vue';
import AppLayout from './Layouts/AppLayout.vue';

const appName = window?.document?.getElementsByTagName('title')[0]?.innerText || 'Laravel';

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: name => {
        const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
        let page = pages[`./Pages/${name}.vue`];
        page.default.layout = name.startsWith('Admin/') ? AdminLayout : AppLayout;
        return page;
    },
    setup({ el, App, props, plugin }) {
        return createApp({ render: () => h(App, props) })
            .use(plugin)
            .component('Head', Head)
            .component('Link', Link)
            .use(ZiggyVue, Ziggy)
            .mount(el);
    },

    progress: {
        color: '#4B5563',
    },
});

AdminLayout.vue

<script setup>
import {computed, ref} from 'vue';
import {BellIcon,} from '@heroicons/vue/24/outline';
import {BuildingOfficeIcon, CheckCircleIcon, MoonIcon, SunIcon,} from '@heroicons/vue/20/solid';
import {useDark, useToggle} from '@vueuse/core';
import {usePage} from '@inertiajs/vue3';
import Search from '../Components/Shared/Search.vue';
import StaticDesktopSideBar from '../Components/Persistent/Admin/Menu/AdminDesktopSideBar.vue';
import MobileAdminSideBar from '../Components/Persistent/Admin/Menu/AdminMobileSideBar.vue';
import ProfileDropdown from '../Components/ProfileDropdown.vue';

const user = computed(() => usePage().props.auth.user);

const isDark = useDark();
const toggleDark = useToggle(isDark);
let greeting = '';
const hour = new Date().getHours();
const times = ['Good morning', 'Good afternoon', 'Good evening'];
let welcomeText = '';

if (hour < 12) welcomeText = times[0];
else if (hour < 18) welcomeText = times[1];
else welcomeText = times[2];
greeting = welcomeText;
const sidebarOpen = ref(false);

</script>

<template>
    <div class="min-h-full">

        <StaticDesktopSideBar/>
        <!--central part-->
        <div class="flex flex-1 flex-col lg:pl-64">
            <div class="flex h-16 flex-shrink-0 border-b border-gray-200 lg:border-none">
                <!-- mobile hamb button and menu -->
                <MobileAdminSideBar/>
                <!-- Search bar -->
                <div class="flex flex-1 justify-between px-4 sm:px-6 lg:mx-auto lg:max-w-6xl lg:px-8">
                    <div class="flex flex-1">
                        <form class="flex w-full md:ml-0" action="#" method="GET">
                            <Search/>
                        </form>
                    </div>
                    <div class="ml-4 flex items-center md:ml-6">
                        <button @click="toggleDark()">
                            <MoonIcon class="w-6 h-6 hover:text-slate-400" v-if="!isDark"></MoonIcon>
                            <SunIcon class="w-6 h-6n hover:text-yellow-300" v-if="isDark"></SunIcon>
                        </button>
                        <button type="button"
                                class="rounded-full p-1 hover:text-slate-400 dark:hover:text-slate-300 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:ring-offset-2">
                            <span class="sr-only">View notifications</span>
                            <BellIcon class="h-6 w-6" aria-hidden="true"/>
                        </button>

                        <ProfileDropdown/>
                    </div>
                </div>
            </div>
            <main class="flex-1 pb-8">
                <!-- Page header -->
                <div class="shadow">
                    <div class="px-4 sm:px-6 lg:mx-auto lg:max-w-6xl lg:px-8">
                        <div class="py-6 md:flex md:items-center md:justify-between lg:border-t lg:border-gray-200">
                            <div class="min-w-0 flex-1">
                                <!-- Profile -->
                                <div class="flex items-center">
                                    <img class="hidden h-16 w-16 rounded-full sm:block"
                                         src="https://workzone.io/storage/profile-photos/kB8We8fP434U2eGGRXlgrznN4vP9DhEk8YCa6Tvn.png"
                                         alt=""/>
                                    <div>
                                        <div class="flex items-center">
                                            <img class="h-20 w-20 rounded-full sm:hidden"
                                                 src="https://workzone.io/storage/profile-photos/kB8We8fP434U2eGGRXlgrznN4vP9DhEk8YCa6Tvn.png"
                                                 alt=""/>
                                            <h1 class="ml-3 text-2xl font-bold leading-7 dark:text-slate-50 sm:truncate sm:leading-9">
                                                {{ greeting }}, {{ user?.name }}
                                            </h1>
                                        </div>
                                        <dl class="mt-6 flex flex-col sm:ml-3 sm:mt-1 sm:flex-row sm:flex-wrap">
                                            <dt class="sr-only">Company</dt>
                                            <dd class="flex items-center text-sm font-medium capitalize sm:mr-6">
                                                <BuildingOfficeIcon class="mr-1.5 h-5 w-5 flex-shrink-0"
                                                                    aria-hidden="true"/>
                                            </dd>
                                            <dt class="sr-only">Account status</dt>
                                            <dd class="mt-3 flex items-center text-sm font-medium capitalize sm:mr-6 sm:mt-0">
                                                <CheckCircleIcon class="mr-1.5 h-5 w-5 flex-shrink-0 text-green-400"
                                                                 aria-hidden="true"/>
                                                Verified account
                                            </dd>
                                        </dl>
                                    </div>
                                </div>
                            </div>
                            <div class="mt-6 flex space-x-3 md:mt-0 md:ml-4">
                                <div class="flex flex-col">
                                    <div v-if="$page.props.flash.message" class="bg-yellow-100">
                                        {{ $page.props.flash.message }}
                                    </div>
                                    <span>Some notification feed here scrolling up when happen??</span>
                                    <span>User send a contact request...</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div>
                    <div class="bg-slate-100 flex w-full pl-12 pt-12 pb-4">
                        <div class="col-start-2">
                            <slot name="heading">Please Add some heading here</slot>
                        </div>
                    </div>

                    <div class="mx-auto max-w-5xl">
                        <slot/>
                    </div>
                </div>

            </main>
        </div>
    </div>
</template>

Roles.vue

<template>
    <div class="mx-auto max-w-5xl">
        <template #heading><h1>Rules</h1></template>
        <div class="p-4 rounded-t-lg">
            <dl class="mt-16 grid grid-cols-1 gap-1 overflow-hidden rounded-xl text-left sm:grid-cols-2 lg:grid-cols-3">
                <div class="flex flex-col bg-white p-4" v-for="role in roles" :key="role.id">
                    <fieldset>
                        <legend class="pb-1 pt-1 flex justify-between w-full text-xs">
                            <span class="flex space-x-2 gap-1 items-center">
                            <span class="rounded transform skew-x-12 bg-orange-500 px-3 py-1 uppercase text-white">
                              {{ role.name }}
                              </span>
                                <span class="text-xs font-normal italic">permissions</span>
                            </span>
                            <span class="flex space-x-2 gap-1">
                                <input type="checkbox"
                                       class="h-4 w-4 rounded border-gray-300 text-orange-500 focus:ring-orange-600">Select all
                            </span>

                        </legend>
                        <div class="mt-4 divide-y divide-gray-200 border-t border-b border-gray-200">
                            <div class="relative flex items-start py-4" v-for="permission in role.permissions" :key="permission.id">
                                <div class="min-w-0 flex-1 text-sm">
                                    <label for="person-1" class="select-none font-medium text-gray-700">
                                        {{ permission.name }}
                                    </label>
                                </div>
                                <div class="ml-3 flex h-5 items-center">
                                    <input id="person-1" name="person-1" type="checkbox"
                                           class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"/>
                                </div>
                            </div>
                        </div>
                    </fieldset>
                </div>
            </dl>
        </div>
    </div>
</template>
nezaboravi commented 1 year ago

Please let me know if i can provide more details to help you understand the issue.

Ifriqiya commented 1 year ago

Try replacing <template #heading><h1>Rules</h1></template> with <div slot="header"><h1>Rules</h1></div>

Source: https://github.com/inertiajs/inertia/issues/171

nezaboravi commented 1 year ago

Thank you I have tried that already before i posted her, and i got two headings. One, set default in AdminLayout, and second set in div slot=header. I have been looking both connected issues that already reported in issue tracker here on inertia.

image
Ifriqiya commented 1 year ago

Maybe having the slot outside the <main></main> section matters.

       <div>
          <slot name="heading" />
        </div>
      <main>
        <slot></slot> //your content
      </main>
nezaboravi commented 1 year ago

Maybe having the slot outside the <main></main> section matters.

       <div>
          <slot name="heading" />
        </div>
      <main>
        <slot></slot> //your content
      </main>

Sorry, i don't think it matters, main is just a tag, and in no way shall define behaviour.

reinink commented 1 year ago

Hey! Thanks so much for your interest in Inertia.js and for sharing this issue/suggestion.

In an attempt to get on top of the issues and pull requests on this project I am going through all the older issues and PRs and closing them, as there's a decent chance that they have since been resolved or are simply not relevant any longer. My hope is that with a "clean slate" me and the other project maintainers will be able to better keep on top of issues and PRs moving forward.

Of course there's a chance that this issue is still relevant, and if that's the case feel free to simply submit a new issue. The only thing I ask is that you please include a super minimal reproduction of the issue as a Git repo. This makes it much easier for us to reproduce things on our end and ultimately fix it.

Really not trying to be dismissive here, I just need to find a way to get this project back into a state that I am able to maintain it. Hope that makes sense! ❤️