rewrite to conform with latest Laravel dropdown element
This commit is contained in:
parent
c5612ba108
commit
2120fc8c4d
@ -1,110 +1,95 @@
|
||||
<template>
|
||||
<transition leave-active-class="duration-200">
|
||||
<div class="relative">
|
||||
<div class="hover:cursor-pointer" @click="show = !show">
|
||||
<slot name="trigger">
|
||||
<svg v-show="!show" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class=""><polyline points="6 9 12 15 18 9"></polyline></svg>
|
||||
<svg v-show="show" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class=""><polyline points="6 9 12 15 18 9"></polyline></svg>
|
||||
</slot>
|
||||
</div>
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
|
||||
|
||||
<div v-show="show" class="fixed inset-0 z-40" @click="show = false"></div>
|
||||
|
||||
<transition enter-active-class="ease-out duration-300"
|
||||
enter-from-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enter-to-class="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave-active-class="ease-in duration-200"
|
||||
leave-from-class="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave-to-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
|
||||
<div v-show="show" @click="show = false" class="flex flex-col absolute right-0 bg-white border border-gray-300 shadow-md w-max z-50">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
maxWidth: {
|
||||
const props = defineProps({
|
||||
align: {
|
||||
type: String,
|
||||
default: '2xl',
|
||||
default: 'right',
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '48',
|
||||
},
|
||||
|
||||
setup(props) {
|
||||
let show = ref(false)
|
||||
|
||||
return { show }
|
||||
},
|
||||
|
||||
mounted() {
|
||||
document.addEventListener('keydown', this.closeOnEscape)
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
document.removeEventListener('keydown', this.closeOnEscape)
|
||||
},
|
||||
|
||||
computed: {
|
||||
maxWidthClass() {
|
||||
return {
|
||||
'sm': 'sm:max-w-sm',
|
||||
'md': 'sm:max-w-md',
|
||||
'lg': 'sm:max-w-lg',
|
||||
'xl': 'sm:max-w-xl',
|
||||
'2xl': 'sm:max-w-2xl',
|
||||
}[this.maxWidth]
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
closeOnEscape(event) {
|
||||
if (event.key === 'Escape' && this.show) {
|
||||
this.show = false
|
||||
}
|
||||
},
|
||||
contentClasses: {
|
||||
type: Array,
|
||||
default: () => ['py-1', 'bg-white'],
|
||||
},
|
||||
})
|
||||
|
||||
// variables
|
||||
let open = ref(false)
|
||||
|
||||
// computed properties
|
||||
const widthClass = computed(() => {
|
||||
return {
|
||||
'48': 'w-48',
|
||||
'52': 'w-52',
|
||||
'56': 'w-56',
|
||||
'60': 'w-60',
|
||||
'64': 'w-64',
|
||||
'72': 'w-72',
|
||||
'80': 'w-80',
|
||||
'96': 'w-96',
|
||||
}[props.width.toString()]
|
||||
})
|
||||
|
||||
const alignmentClasses = computed(() => {
|
||||
if (props.align === 'left') {
|
||||
return 'origin-top-left left-0'
|
||||
}
|
||||
|
||||
if (props.align === 'right') {
|
||||
return 'origin-top-right right-0'
|
||||
}
|
||||
|
||||
return 'origin-top'
|
||||
})
|
||||
|
||||
// lifecycle hooks
|
||||
onMounted(() => {
|
||||
document.addEventListener('keydown', closeOnEscape)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('keydown', closeOnEscape)
|
||||
})
|
||||
|
||||
// methods
|
||||
const closeOnEscape = (event) => {
|
||||
if (open.value && event.key === 'Escape') {
|
||||
open.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*.rotate { animation: rotation 2s infinite linear; }
|
||||
<template>
|
||||
<div class="relative">
|
||||
<div @click="open = ! open">
|
||||
<slot name="trigger"></slot>
|
||||
</div>
|
||||
|
||||
@keyframes rotation {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(359deg); }
|
||||
}
|
||||
<!-- Full Screen Dropdown Overlay -->
|
||||
<div v-show="open" class="fixed inset-0 z-40" @click="open = false"></div>
|
||||
|
||||
.dropdown-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
background-color: hsl(0, 0%, 100%);
|
||||
border: 1px solid hsl(240, 4.9%, 83.9%);
|
||||
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.dropdown-link {
|
||||
display: flex;
|
||||
padding: 1rem 0.5rem 1rem 0.5rem;
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.dropdown-link:hover {
|
||||
background-color: hsl(240, 4.8%, 95.9%);
|
||||
}
|
||||
|
||||
.dropdown-link:focus {
|
||||
background-color: hsl(240, 4.8%, 95.9%);
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
}*/
|
||||
</style>
|
||||
<transition
|
||||
enter-active-class="transition ease-out duration-200"
|
||||
enter-from-class="transform opacity-0 scale-95"
|
||||
enter-to-class="transform opacity-100 scale-100"
|
||||
leave-active-class="transition ease-in duration-75"
|
||||
leave-from-class="transform opacity-100 scale-100"
|
||||
leave-to-class="transform opacity-0 scale-95"
|
||||
>
|
||||
<div
|
||||
v-show="open"
|
||||
class="absolute z-50 mt-2 rounded-md shadow-lg"
|
||||
:class="[widthClass, alignmentClasses]"
|
||||
style="display: none;"
|
||||
@click="open = false"
|
||||
>
|
||||
<div class="rounded-md ring-1 ring-black ring-opacity-5" :class="contentClasses">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
Loading…
x
Reference in New Issue
Block a user