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

weird propagation behaviour (Menu inside another) #1044

Open
demiro opened this issue Jul 13, 2024 · 0 comments
Open

weird propagation behaviour (Menu inside another) #1044

demiro opened this issue Jul 13, 2024 · 0 comments

Comments

@demiro
Copy link

demiro commented Jul 13, 2024

So, I have this scenario (which is not uncommon)... (especially in submenu > menu) situations...

<HelpTip>
    <template #trigger>
        <SelectButton ... />
    </template>
    some content
</HelpTip>

where SelectButton is

<Dropdown>
    <button>open</button>
    <template #popper>
        ...
    </template>
</Droptdown>

And HelpTip is:

<script setup lang="ts">
  import { Dropdown } from "floating-vue";
  import { ref } from "vue";
  import IconHelp from "~icons/material-symbols/help-outline";

  const props = defineProps<{
    text?: string;
  }>();

  const dropdownRef = ref<InstanceType<typeof Dropdown> | null>(null);

  const hideTooltip = (event: Event) => {
    if (event.target && (event.target as HTMLElement).closest(".trigger")) {
      if (dropdownRef.value) {
        dropdownRef.value.hide();
        // event.stopImmediatePropagation();
      }
    }
  };
</script>
<template>
  <Dropdown ref="dropdownRef" placement="top" :delay="{ show: 0, hide: 0 }" :triggers="['hover', 'focus']">
    <div v-if="$slots.trigger" @click.capture="hideTooltip">
      <slot name="trigger"></slot>
    </div>
    <button v-if="!$slots['trigger']" class="menu-trigger icon-rounded tiny" type="button">
      <IconHelp />
    </button>
    <template #popper>
      <div class="wrapper">
        <aside>
          <IconHelp class="big" />
        </aside>
        <main>
          {{ text }}
          <slot></slot>
        </main>
      </div>
    </template>
  </Dropdown>
</template>

Now, I think is pretty self explanatory what I want to achieve... which is
when I hover over an element, that is wrapped inside a <HelpTip><template #trigger>... the content of HelpTip should display as tooltip...

Works great.

Next thing I want is for any click action inside the <template #trigger> to close the tooltip - BUT STILL ALLOW the action to happen...

What actually happens...

if I have logic like this:

const hideTooltip = (event: Event) => {
    if (event.target && (event.target as HTMLElement).closest(".trigger")) {
      if (dropdownRef.value) {
        dropdownRef.value.hide();
      }
    }
};

the action (click) executes but the TOOLTIP does not hide...

but if I do this

const hideTooltip = (event: Event) => {
  if (event.target && (event.target as HTMLElement).closest(".trigger")) {
    if (dropdownRef.value) {
      dropdownRef.value.hide();
      event.stopImmediatePropagation();
    }
  }
};

the tooltip hides, and obviously the click event does not get triggered :/

and this happens ONLY where inside I have a nested dropdown ... because If I have

<HelpTip>
  <template #trigger>
    <button @click="someaction">button text</button>
  </template>
  TEST
</HelpTip>

It works as it should, the click get's executed and the "TEST" tooltip gets displayed.

so clearly the Dropdown component is hijacking the click event propagation and not propagating it correctly?

Any Ideas on how to tackle this thing would be great!

Here are some simplified live examples

Normal button
Nested dropdown

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

No branches or pull requests

1 participant