tailwindlabs / headlessui

Completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.
https://headlessui.com
MIT License
26.19k stars 1.09k forks source link

kebab-case Dialog doesn't work with vue #1793

Closed lava83 closed 2 years ago

lava83 commented 2 years ago

What package within Headless UI are you using?

@headlessui/vue@latest

What version of that package are you using?

v1.6.7

What browser are you using?

Chrome

Reproduction URL

<template>
    <div class="fixed inset-0 flex items-center justify-center">
        <button
            type="button"
            class="rounded-md bg-black bg-opacity-20 px-4 py-2 text-sm font-medium text-white hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
            @click="openModal"
        >
            Open dialog
        </button>
    </div>
    <transition-root
        appear
        :show="isOpen"
        as="template"
    >
        <dialog
            as="div"
            class="relative z-10"
            @close="closeModal"
        >
            <transition-child
                as="template"
                enter="duration-300 ease-out"
                enter-from="opacity-0"
                enter-to="opacity-100"
                leave="duration-200 ease-in"
                leave-from="opacity-100"
                leave-to="opacity-0"
            >
                <div class="fixed inset-0 bg-black bg-opacity-25" />
            </transition-child>

            <div class="fixed inset-0 overflow-y-auto">
                <div class="flex min-h-full items-center justify-center p-4 text-center">
                    <transition-child
                        as="template"
                        enter="duration-300 ease-out"
                        enter-from="opacity-0 scale-95"
                        enter-to="opacity-100 scale-100"
                        leave="duration-200 ease-in"
                        leave-from="opacity-100 scale-100"
                        leave-to="opacity-0 scale-95"
                    >
                        <dialog-panel
                            class="w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all"
                        >
                            <dialog-title
                                as="h3"
                                class="text-lg font-medium leading-6 text-gray-900"
                            >
                                Payment successful
                            </dialog-title>
                            <div class="mt-2">
                                <p class="text-sm text-gray-500">
                                    Your payment has been successfully submitted. We’ve sent you
                                    an email with all of the details of your order.
                                </p>
                            </div>

                            <div class="mt-4">
                                <button
                                    type="button"
                                    class="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
                                    @click="closeModal"
                                >
                                    Got it, thanks!
                                </button>
                            </div>
                        </dialog-panel>
                    </transition-child>
                </div>
            </div>
        </dialog>
    </transition-root>
</template>

<script setup>

import { ref } from 'vue';
import {
    TransitionRoot,
    TransitionChild,
    Dialog,
    DialogPanel,
    DialogTitle,
} from '@headlessui/vue';

const isOpen = ref(true);

function closeModal() {
    isOpen.value = false;
}
function openModal() {
    isOpen.value = true;
}

</script>

Describe your issue

When I want to use the dialogue component as kebab-case, it already complains with: Dialog is defined but never used. although I use the component in the template area... See script above.

image image

I think it has something to do with this html tag: https://developer.mozilla.org/en/docs/Web/HTML/Element/dialog

If I use the component in PascalCase notation, it works again.

I have now helped myself by importing Dialog as an alias VDialog, but it is not pretty.

adamwathan commented 2 years ago

Hey! If you want to use lowercase component names you’ll have to alias it like you’ve found. Nothing we can really do here, that’s just how things work with Vue. We could change the component name but that would make the experience worse for everyone using PascalCase (like we use in the docs) and it’s not necessary anyways since you can alias it to whatever you want when you import it.

Generally I would just recommend using PascalCase, this is what the Vue style guide recommends as well:

https://vuejs.org/style-guide/rules-strongly-recommended.html#component-name-casing-in-templates