Giter Club home page Giter Club logo

Comments (6)

RobinMalfait avatar RobinMalfait commented on August 22, 2024 1

By default we use a button, and we put a bunch of properties on that button. If you use a custom button (like how you did it) then we put all those properties on the custom component. If I explore this in codesandbox than you can see that all the correct stuff is applied (You can either inspect the DOM or the attrs) https://codesandbox.io/s/headlessuivue-menu-example-forked-vvzft?file=/src/App.vue

However, the actual DOM ref is not applied correctly. I have to come back to this issue because I am not 100% sure why this is happening (or rather not happening).

from headlessui.

elilabes avatar elilabes commented on August 22, 2024

Hey @RobinMalfait - I was just wondering if there was any update on this issue? I'm currently just wrapping the component in a div so that it is not the first child of the MenuButton, but that causes the focus functionality on close to not work.

Happy to provide any more details if needed 😄

from headlessui.

RobinMalfait avatar RobinMalfait commented on August 22, 2024

Hey! Sorry for the very long wait.
I don't know exactly what your particular example doesn't work.

I know that Vue has "special" behaviour implemented for refs and class. I think (but am not certain) that there is a limitation that the ref is not correctly forwarded to the deeply nested actual DOM node. I still have to take a deeper look if I can make that more clear or not.

That said, here is an alternative implementation that might work for you out of the box: https://codesandbox.io/s/headlessuivue-menu-example-forked-vvzft?file=/src/App.vue

from headlessui.

a47ae avatar a47ae commented on August 22, 2024

Hey, I have a similar error but I am not using the slot to render the custom button, but the as prop.

Example code for using a custom component

<template>
  <Menu>
    <MenuButton ref="reference" :as="as">
      Demo Button
    </MenuButton>
    
    <div ref="popper" class="w-56">
      <!-- menu content -->
    </div>
  </Menu>
</template>

<script lang="ts">
import { DemoButton } from 'my-ui-lib'
import { Menu, MenuButton } from "@headlessui/vue";

export default defineComponent({
  components: {
    Menu,
    MenuButton,
  },
  setup() {
    const reference = ref(null) as Ref<null | { el: { $el: HTMLElement } }>;
    const popper = ref(null) as Ref<null | HTMLElement>;

    onMounted(() => {
      watchEffect((onInvalidate) => {
        const popperEl = popper.value;
        const referenceEl = reference.value?.el?.$el;

        if (!(referenceEl instanceof HTMLElement)) return;
        if (!(popperEl instanceof HTMLElement)) return;

        const { destroy } = createPopper(referenceEl, popperEl, {
          placement: "bottom",
          strategy: "fixed",
          modifiers: [{ name: "offset", options: { offset: [0, 10] } }],
        });

        onInvalidate(destroy);
      });
    });

    return {
      reference,
      popper,
      as: DemoButton,
    };
  },
});
</script>

While the above approach seems to work I got two errors in the console.

[Vue warn]: Property "id" was accessed during render but is not defined on instance.

and

[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance. 

But the id seems to be set correctly on my component and also the other props that are controlled through headlessui are passed correctly.

While digging in the debugger I think I found the reason for the error.
It appears to be this line: 'aria-labelledby': api.buttonRef.value?.id

Because in the above case, the button ref is not an instance of HTMLElement but a reference to a Vue component the id property does not exists on api.buttonRef.value. Instead it exists on api.buttonRef.value.$el.id

When changing this line, the error about accessing id disappears, but then it breaks for instances where no custom component is used as the button. So probably there needs to be some kind of check what kind of reference api.buttonRef is.

I could not find out what the reason for the second error is, but is seems to also be connected to using a custom component.

from headlessui.

a47ae avatar a47ae commented on August 22, 2024

I encountered another error which also seems to be caused by api.buttonRef not being an HTMLElement.

TypeError: _api$buttonRef$value.focus is not a function

which happens in for example in this line nextTick(() => api.buttonRef.value?.focus({ preventScroll: true }))

I think this also explains the not working focus described by @elilabes

from headlessui.

RobinMalfait avatar RobinMalfait commented on August 22, 2024

Hey!

This should be fixed, and will be available in the next release.
You can already try it using npm install @headlessui/vue@dev or yarn add @headlessui/vue@dev.

Fixed it in #249, thanks for the extra pointers @a47ae.

Here is an example with the new (dev) version: https://codesandbox.io/s/headlessuivue-menu-example-forked-vvzft?file=/src/App.vue

from headlessui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.