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

Class passed to component is lost in the portal #101

Open
lazlo-bonin opened this issue Jan 24, 2018 · 7 comments
Open

Class passed to component is lost in the portal #101

lazlo-bonin opened this issue Jan 24, 2018 · 7 comments

Comments

@lazlo-bonin
Copy link

I use portal-vue in order to move all my modals at the top level for z-ordering. My dialog component setup is like so:

<template>
    <portal to="dialogs">
        <div class="dialog-mask">
            <div class="dialog-container">
                ...

When I try to use the component, I often do something like:

<dialog class="myDialogClass">...</dialog>

However, when the <div> is rendered in the portal-target, it only has the dialog-mask class, not dialog-mask myDialogClass.

I'm struggling to get the class property to bind. I could use a custom dialogClass prop and do it manually, but I'd rather use vue's built-in clear syntax.

Am I missing something?

@LinusBorg
Copy link
Owner

LinusBorg commented Jan 25, 2018

You are missing that the class that you define on the component will be added to its root element - which is the portal, not the div inside it.

However, you can set inheritAttrs: false in the component containing the portal and then use $attrs to pass any attributes defined in the component to that div instead:

<div class="dialog-mask" v-bind="$attrs">

Please see the Vue documentation for those two properties of you want to learn more.

@lazlo-bonin
Copy link
Author

lazlo-bonin commented Jan 25, 2018

The Vue documentation states:

Note: this option does not affect class and style bindings.

Any other solution?

Edit: Seeing this issue, I ended up using a custom prop after all:

vuejs/vue#6144

@LinusBorg
Copy link
Owner

Oh, right, forgot about that limitation.

I will add this to the caveats section in the docs later.

@tmorehouse
Copy link

If the dialog has a single root element, wouldn't the slim option make the inner content the root element (this.$el) and the class would be placed in it? or is that relationship lost during transport?

@tmorehouse
Copy link

Just realized that slim is only applicable to disabled mode.

I also tried setting portal's tag to transition (which has the nice effect of rendering <!----> instead of a visually hidden div), but still the same effect of not transferring the class to the root element.

@LinusBorg
Copy link
Owner

or is that relationship lost during transport

This. There's really no way to make this work.

@GerardRodes
Copy link

It feels hacky but i solved this using $vnode.data.staticClass

<template>
  <portal to="root">
    <div :class="$vnode.data.staticClass" />
  </portal>
</template>

This way class (and potentially any data inside vnode) can be pass down through the portal

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

No branches or pull requests

4 participants