RobinCK/vue-popper

Popper content must be first child element?

schrockwell opened this issue · 4 comments

I ran into an error by putting my reference slot button as the first child of the <popper> component, e.g.:

<popper>
  <button slot="reference">Don't do this!</button>
  <div class="popper">foo bar</div>
</popper>

In reality, the popover content div must be the first element, I believe due to this line:

https://github.com/RobinCK/vue-popper/blob/master/src/component/popper.js.vue#L207

Please either (a) add the option to specify a new popper slot explicitly, and/or (b) mention in the docs that the popper content must come first.

@schrockwell did you find any workaround on this?

(Set a simple fiddle illustrating the problem to help debugging help)

Actually i think the problem is this: basically, content element it's always pointing to the first node of the default slot and it's not filtering empty text space vnodes, when we should be selecting the first element that is a valid HTMLElement node.

mounted() {
this.referenceElm = this.reference || this.$slots.reference[0].elm;
this.popper = this.$slots.default[0].elm;

I might give a try at fixing this.

I'll take a look at it later, but if it helps this should work :)

 mounted(){
     this.getElements()
  },
  methods: {
      /**
       * @desc only accept HTMLElement nodes, filtering textnodes and nasty whitespace nodes
       * @param {Array} slotArray - slot vnodes array
       */
      filterSlots(slotArray){
        return slotArray.filter(vnode => vnode.tag !== undefined);
      },

      /**
       * @desc get HTMLElement nodes for both reference and popper
       */
      getElements(){
        this.referenceElm = this.$slots.reference[0].elm;
        let defaultSlotEls = filterSlots(this.$slots.default);

        if(defaultSlotEls.length > 1){
          throw new Error("We only allow a single root element for default slot")
        } else {
          this.popper = defaultSlotEls[0].elm;
        }
      },

Thanks for your work on this man!

Of course the source URL link changed because master changed, but yes that was the line I was referencing.

My workaround was to just put the popover content first. :) Yours seems like an actual fix, thanks.