Comments (6)
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.
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.
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.
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.
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.
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)
- `RadioGroup` do not render hidden inputs when given a `name` HOT 1
- Sibling Dialogs can't touch-scroll on mobile HOT 2
- Combobox: When ComboboxInput is clicked combobox gets closed HOT 2
- React warning `Warning: Function components cannot be given refs.` and wrong visual placement of combobox options, when using `as={React.Fragment}` alongside Framer Motion's `motion.div` and `AnimatePresence` for immediate comboboxes
- Menu gets closed when user click outside, but event propagation seems suppressed HOT 1
- Better support for exactOptionalPropertyTypes: true
- Combobox virtual types don't work when multiple is true
- On Android/Chrome, opening Dialog results in too much right-padding if the page has horizontal overflow
- Unable to manually close Menu Component
- Listbox not closing when scrolling the page HOT 2
- ListBoxButton remains active on mouse exit HOT 1
- [Dialog] `DialogPanel` with framer motion and `as` prop HOT 2
- On iOS Safari, scrolling is not possible or limited if an input in a Dialog is focused
- Passing ref to PopoverButton the ref get nullified on rerenders
- Display value not present in the DOM
- v1 docs for vue 400 bad request HOT 1
- boolean form values are incorrect
- User select is not working inside ComboboxOptions HOT 2
- Inert is over extending into elements inside the combo box HOT 1
- transition attribute name collision when using framer motion HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from headlessui.