kenhyuwa / litepie-datepicker

Litepie Datepicker is a date range picker component for Vue.js and Tailwind CSS, dependent to day.js.
https://litepie.com
MIT License
373 stars 75 forks source link

Trigger don't work in tailwind modal #23

Closed nachiomdq closed 3 years ago

nachiomdq commented 3 years ago

Hi, i have a strange situation. Datepicker works ok in a custom page, but when i try to show in a modal, trigger doesn't work and datepicker doesn't show.

Captura de pantalla 2021-06-03 a las 10 54 34

As you can see, display:none is the status of the class, even when i focused or used custom trigger.

I tried without a modal and it's work ok...

Thanks in advance.

kenhyuwa commented 3 years ago

are you using teleport for modal?

tbordinat commented 3 years ago

Hi ! I think I had the same problem using the headlessui components. This slide-over precisely https://tailwindui.com/components/application-ui/overlays/slide-overs#component-b76ed25b74c40b7f3a181393e2b7742f

I had to remove the <Dialog> to have it work

nachiomdq commented 3 years ago

are you using teleport for modal?

Yes, i'm using teleport (headlessui use it). But recently i move from headlessui 1.0.0 to 1.1.0. I'm rollback that change and see if the issue still happens.

nachiomdq commented 3 years ago

Hi ! I think I had the same problem using the headlessui components. This slide-over precisely https://tailwindui.com/components/application-ui/overlays/slide-overs#component-b76ed25b74c40b7f3a181393e2b7742f

I had to remove the <Dialog> to have it work

Ok, thanks mate. But i need that

component. Also i tried without headlessui (build the modal by html) but still happens.

nachiomdq commented 3 years ago

With headlessui 1.0.0 seems to work. 1.1.0 not work. 1.2.0 not work.

kenhyuwa commented 3 years ago

some trick,

<template>
<!-- @headlessui/vue -->
<litepie-datepicker ref="litepieRef"
      v-model="dateValue"
      @click="litepieRef.isShow = !litepieRef.isShow"
  ></litepie-datepicker>
<!-- @headlessui/vue -->
<template>

<script>
export default {
   setup() {
     const litepieRef = ref(null)

     return {
       litepieRef
     }
   }
}
</script>
nachiomdq commented 3 years ago

some trick,

<template>
<!-- @headlessui/vue -->
<litepie-datepicker ref="litepieRef"
      v-model="dateValue"
      @click="litepieRef.isShow = !litepieRef.isShow"
  ></litepie-datepicker>
<!-- @headlessui/vue -->
<template>

<script>
export default {
   setup() {
     const litepieRef = ref(null)

     return {
       litepieRef
     }
   }
}
</script>

ohh Nice workaround!

Works great!

Thank you!

tbordinat commented 3 years ago

Nice, it works fine for me too ! Thank you very much :)

rifky999 commented 1 year ago

some trick,

<template>
<!-- @headlessui/vue -->
<litepie-datepicker ref="litepieRef"
      v-model="dateValue"
      @click="litepieRef.isShow = !litepieRef.isShow"
  ></litepie-datepicker>
<!-- @headlessui/vue -->
<template>

<script>
export default {
   setup() {
     const litepieRef = ref(null)

     return {
       litepieRef
     }
   }
}
</script>

Seems close when click outside the component does not work by this

rifky999 commented 1 year ago

To handling the click outside event, i add directive :

app.directive('clickOutside', {
    beforeMount: (selectedEl, binding) => {
        selectedEl.eventSetDrag = () => {
            selectedEl.setAttribute('data-dragging', 'yes')
        }
        selectedEl.eventClearDrag = () => {
            selectedEl.removeAttribute('data-dragging')
        }
        selectedEl.eventOnClick = (event: MouseEvent) => {
            const dragging = selectedEl.getAttribute('data-dragging')
            // Check that the click was outside the el and its children, and wasn't a drag
            if (
                !(
                    selectedEl == event.target ||
                    selectedEl.contains(event.target)
                ) &&
                !dragging
            ) {
                // call method provided in attribute value
                binding.value(event)
            }
        }

        const initListenerByElement = (el: Element | Document) => {
            el.addEventListener('touchstart', selectedEl.eventClearDrag)
            el.addEventListener('touchmove', selectedEl.eventSetDrag)
            el.addEventListener('click', selectedEl.eventOnClick)
            el.addEventListener('touchend', selectedEl.eventOnClick)
        }

        initListenerByElement(document)

        // Listener when the element is inside the drawer
        const elODrawers = document.querySelectorAll('.el-drawer')
        elODrawers.forEach(elDrawer => initListenerByElement(elDrawer))
    },
    unmounted: selectedEl => {
        const removeListenerByElement = (el: Element | Document) => {
            el.removeEventListener('touchstart', selectedEl.eventClearDrag)
            el.removeEventListener('touchmove', selectedEl.eventSetDrag)
            el.removeEventListener('click', selectedEl.eventOnClick)
            el.removeEventListener('touchend', selectedEl.eventOnClick)
        }

        removeListenerByElement(document)
        selectedEl.removeAttribute('data-dragging')

        // Remove Listener when the element is inside the drawer
        const elDrawers = document.querySelectorAll('.el-drawer')
        elDrawers.forEach(elDrawer => removeListenerByElement(elDrawer))
    }
})

Example usage :

<label
 v-click-outside="() => (elLitepieDatepicker.isShow = false)"
 @click="elLitepieDatepicker.isShow = !elLitepieDatepicker.isShow"
>
Date Range
</label>