tangle_indexer


git clone https://radroots.dev/git/tangle_indexer.git
Log | Files | Refs | Submodules | LICENSE

dropdown-nested.svelte (1878B)


      1 <script lang="ts">
      2     import { fmt_cl } from "@radroots/apps-lib";
      3     import { onDestroy, onMount, type Snippet } from "svelte";
      4 
      5     let {
      6         basis,
      7         primary,
      8         dropdown,
      9     }: {
     10         basis?: {
     11             classes_primary?: string;
     12             classes_dropdown?: string;
     13         };
     14         primary: Snippet;
     15         dropdown: Snippet;
     16     } = $props();
     17 
     18     let el_container: HTMLDetailsElement | null = $state(null);
     19     let el_dropdown: HTMLElement | null = $state(null);
     20 
     21     let shift_x = $state(0);
     22 
     23     $effect(() => {
     24         const rect_primary = el_container?.getBoundingClientRect();
     25         const rect_dropdown = el_dropdown?.getBoundingClientRect();
     26         if (rect_primary && rect_dropdown)
     27             shift_x = rect_dropdown.width - rect_primary.width;
     28     });
     29 
     30     const handle_click = (event: MouseEvent) => {
     31         if (!el_container || !el_dropdown) return;
     32         if (
     33             !el_container.contains(event.target as Node) ||
     34             el_dropdown.contains(event.target as Node)
     35         )
     36             el_container.open = false;
     37     };
     38 
     39     onMount(() => {
     40         document.addEventListener("click", handle_click);
     41     });
     42 
     43     onDestroy(() => {
     44         document.removeEventListener("click", handle_click);
     45     });
     46 </script>
     47 
     48 <details bind:this={el_container} class="dropdown dropdown-bottom">
     49     <summary class={`${fmt_cl(basis?.classes_primary)} flex`}>
     50         {@render primary()}
     51     </summary>
     52     <ul
     53         bind:this={el_dropdown}
     54         class={`dropdown-content flex flex-col pt-1`}
     55         style={`transform: translateX(-${shift_x}px);`}
     56     >
     57         <ul
     58             class={`z-50 ${fmt_cl(
     59                 basis?.classes_dropdown || `menu min-w-52 p-2 bg-white shadow`,
     60             )} flex flex-col w-full justify-center items-center`}
     61         >
     62             {@render dropdown()}
     63         </ul>
     64     </ul>
     65 </details>