themesberg / flowbite-svelte

Official Svelte components built for Flowbite and Tailwind CSS
https://flowbite-svelte.com
MIT License
2.17k stars 267 forks source link

Dropdown is broken on Safari #1067

Open ollyde opened 1 year ago

ollyde commented 1 year ago

Describe the bug

When using a bind with open the drop-down doesn't work on Safari (mobile and desktop)

Reproduction

Works on everything

<Button>Some button</Button>
<Dropdown>
   <span class="p-16">Drop down test</span>
</Dropdown>

Does not work on Safari mobile or desktop

<script>
    let isOpen = false;
</script>

<Button on:click={() => !isOpen} >Some button</Button>
<Dropdown bind:open={isOpen}>
   <span class="p-16">Drop down test</span>
</Dropdown>

Flowbite version and System Info

System:
    OS: macOS 13.5.2
    CPU: (10) arm64 Apple M1 Max
    Memory: 12.50 GB / 64.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.3.0 - /opt/homebrew/bin/node
    npm: 9.6.7 - /opt/homebrew/bin/npm
    pnpm: 8.6.3 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 116.0.5845.187
    Safari: 16.6
  npmPackages:
    vite: ^4.1.4 => 4.1.4
ollyde commented 1 year ago

For anyone else who gets this bug, here is a temporary drop-down that works perfect.

<script lang="ts">
  import { browser } from "$app/environment";
  import { onDestroy } from "svelte";
  import { fade } from "svelte/transition";

  export let isOpen = false;

  let dropdown: any;

  function toggleDropdown() {
    isOpen = !isOpen;
  }

  function handleClickOutside(event: any) {
    if (dropdown && !dropdown.contains(event.target)) {
      isOpen = false;
    }
  }

  onDestroy(() => {
    if (browser) {
      document.removeEventListener("click", handleClickOutside);
    }
  });

  if (browser) {
    document.addEventListener("click", handleClickOutside);
  }
</script>

<div class="dropdown" bind:this={dropdown}>
  <button on:click={toggleDropdown} class="dropdown-toggle"> <slot name="button">Dropdown</slot> </button>

  {#if isOpen}
    <div class="dropdown-menu bg-white rounded-sm shadow-md drop-shadow-sm" transition:fade|local={{ duration: 100 }}>
      <slot />
    </div>
  {/if}
</div>

<style>
  .dropdown {
    position: relative;
    display: inline-block;
  }

  .dropdown-toggle {
    cursor: pointer;
  }

  .dropdown-menu {
    margin-top: 8px;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 1000;
    transform: translateX(-50%); /* Adjust positioning */
    left: 50%; /* Adjust positioning */
  }
</style>