Files

54 lines
2.6 KiB
PHP

{{--
Navigation bar dropdown. The panel is teleported to <body> and positioned under the
trigger, because the bar's link container clips overflow (overflow-hidden).
Expects: $label, $active (bool); the slot holds <x-jetstream.dropdown-link> items.
--}}
@props(['label', 'active' => false])
@php
$classes = $active
? 'inline-flex items-center px-1 pt-1 border-theme-muted text-xs md:text-sm font-medium leading-5 text-theme-primary hover:text-theme-secondary focus:outline-none whitespace-nowrap'
: 'inline-flex items-center px-1 pt-1 border-transparent text-xs md:text-sm font-medium leading-5 text-theme-primary hover:text-theme-secondary hover:border-theme-border focus:outline-none focus:text-theme-primary transition whitespace-nowrap';
@endphp
<div x-data="{
open: false,
top: 0,
left: 0,
toggle() {
const rect = this.$refs.trigger.getBoundingClientRect();
this.top = rect.bottom + 8;
this.left = Math.min(rect.left, window.innerWidth - 208);
this.open = !this.open;
},
}"
@keydown.escape.window="open = false"
@resize.window="open = false"
class="inline-flex">
<button type="button" x-ref="trigger" @click="toggle()" :aria-expanded="open.toString()" aria-haspopup="true"
{{ $attributes->merge(['class' => $classes]) }}>
{{ $label }}
<svg class="ml-1 h-4 w-4 transition-transform" :class="{ 'rotate-180': open }" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
</svg>
</button>
<template x-teleport="body">
<div x-show="open" x-cloak
@click.outside="if (!$refs.trigger.contains($event.target)) open = false"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="transform opacity-0 scale-95"
x-transition:enter-end="transform opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"
:style="`top: ${top}px; left: ${left}px`"
class="fixed z-[90] w-48 rounded-md shadow-lg origin-top-left"
role="menu">
<div class="rounded-md ring-1 ring-black ring-opacity-5 py-1 bg-theme-background">
{{ $slot }}
</div>
</div>
</template>
</div>