modal with vimeo player
							parent
							
								
									0511ab89cd
								
							
						
					
					
						commit
						bd6efb24b6
					
				@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="fixed inset-0 bg-black/50 z-5 transition duration-300" />
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { ref } from 'vue'
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  Dialog,
 | 
				
			||||||
 | 
					  DialogPanel,
 | 
				
			||||||
 | 
					  TransitionChild,
 | 
				
			||||||
 | 
					  TransitionRoot,
 | 
				
			||||||
 | 
					} from '@headlessui/vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = withDefaults(
 | 
				
			||||||
 | 
					  defineProps<{
 | 
				
			||||||
 | 
					    modelValue?: boolean
 | 
				
			||||||
 | 
					    persistent?: boolean
 | 
				
			||||||
 | 
					    fullscreen?: boolean
 | 
				
			||||||
 | 
					  }>(),
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    modelValue: false,
 | 
				
			||||||
 | 
					    persistent: false,
 | 
				
			||||||
 | 
					    fullscreen: false,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const emit = defineEmits<{
 | 
				
			||||||
 | 
					  (e: 'update:modelValue', value: boolean): void
 | 
				
			||||||
 | 
					}>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { modelValue } = toRefs(props)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const isOpen = ref(modelValue.value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(modelValue, (value) => {
 | 
				
			||||||
 | 
					  isOpen.value = value
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function closeModal() {
 | 
				
			||||||
 | 
					  isOpen.value = false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function openModal() {
 | 
				
			||||||
 | 
					  isOpen.value = true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onModalClose() {
 | 
				
			||||||
 | 
					  if (!props.persistent)
 | 
				
			||||||
 | 
					    closeModal()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(isOpen, (value) => {
 | 
				
			||||||
 | 
					  emit('update:modelValue', value)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const api = {
 | 
				
			||||||
 | 
					  isOpen,
 | 
				
			||||||
 | 
					  open: openModal,
 | 
				
			||||||
 | 
					  close: closeModal,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					provide('modal', api)
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <ClientOnly>
 | 
				
			||||||
 | 
					    <slot name="activator" :open="openModal" :on="{ click: openModal }" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <TransitionRoot appear :show="isOpen" as="template">
 | 
				
			||||||
 | 
					      <Dialog as="div" class="relative z-10" @close="onModalClose">
 | 
				
			||||||
 | 
					        <TransitionChild
 | 
				
			||||||
 | 
					          as="template"
 | 
				
			||||||
 | 
					          enter="duration-300 ease-out"
 | 
				
			||||||
 | 
					          enter-from="opacity-0"
 | 
				
			||||||
 | 
					          enter-to="opacity-100"
 | 
				
			||||||
 | 
					          leave="duration-200 ease-in"
 | 
				
			||||||
 | 
					          leave-from="opacity-100"
 | 
				
			||||||
 | 
					          leave-to="opacity-0"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <div class="fixed inset-0 bg-black bg-opacity-25" />
 | 
				
			||||||
 | 
					        </TransitionChild>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="fixed inset-0 overflow-y-auto">
 | 
				
			||||||
 | 
					          <div
 | 
				
			||||||
 | 
					            class="flex min-h-full items-center justify-center text-center"
 | 
				
			||||||
 | 
					            :class="{
 | 
				
			||||||
 | 
					              'p-4': !fullscreen,
 | 
				
			||||||
 | 
					            }"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <TransitionChild
 | 
				
			||||||
 | 
					              as="template"
 | 
				
			||||||
 | 
					              enter="duration-300 ease-out"
 | 
				
			||||||
 | 
					              enter-from="opacity-0 scale-95"
 | 
				
			||||||
 | 
					              enter-to="opacity-100 scale-100"
 | 
				
			||||||
 | 
					              leave="duration-200 ease-in"
 | 
				
			||||||
 | 
					              leave-from="opacity-100 scale-100"
 | 
				
			||||||
 | 
					              leave-to="opacity-0 scale-95"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              <DialogPanel
 | 
				
			||||||
 | 
					                class="w-full transform overflow-hidden bg-white text-left align-middle shadow-xl transition-all"
 | 
				
			||||||
 | 
					                :class="{
 | 
				
			||||||
 | 
					                  'h-screen': fullscreen,
 | 
				
			||||||
 | 
					                  'max-w-[85%] rounded-lg': !fullscreen,
 | 
				
			||||||
 | 
					                }"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <slot />
 | 
				
			||||||
 | 
					              </DialogPanel>
 | 
				
			||||||
 | 
					            </TransitionChild>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </Dialog>
 | 
				
			||||||
 | 
					    </TransitionRoot>
 | 
				
			||||||
 | 
					  </ClientOnly>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { DialogDescription } from '@headlessui/vue'
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <DialogDescription class="px-4 py-3 text-sm text-gray-800">
 | 
				
			||||||
 | 
					    <slot />
 | 
				
			||||||
 | 
					  </DialogDescription>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					// import { ref } from 'vue'
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="px-4 py-3">
 | 
				
			||||||
 | 
					    <slot />
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { DialogTitle } from '@headlessui/vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface Props {
 | 
				
			||||||
 | 
					  dismissable?: boolean
 | 
				
			||||||
 | 
					  titleClass?: string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defineProps<Props>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const api = inject('modal')
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <DialogTitle
 | 
				
			||||||
 | 
					    as="div"
 | 
				
			||||||
 | 
					    class="flex gap-2 justify-between items-center px-4 pt-3"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
 | 
					    <h3
 | 
				
			||||||
 | 
					      class="text-lg font-medium leading-6 text-gray-900"
 | 
				
			||||||
 | 
					      :class="titleClass"
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <slot />
 | 
				
			||||||
 | 
					    </h3>
 | 
				
			||||||
 | 
					    <slot v-if="dismissable" name="dismissable">
 | 
				
			||||||
 | 
					      <button
 | 
				
			||||||
 | 
					        class="text-2xl text-gray-500 appearance-none px-2 -mr-2"
 | 
				
			||||||
 | 
					        @click="api.close"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        ×
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
 | 
					    </slot>
 | 
				
			||||||
 | 
					  </DialogTitle>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
					Loading…
					
					
				
		Reference in New Issue