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