SlideOver.vue 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. <template>
  2. <div>
  3. <transition v-if="show" name="fade" appear>
  4. <div class="fixed inset-0 z-20 transition-opacity" @keydown.esc="close()">
  5. <div
  6. class="absolute inset-0 bg-primaryLight opacity-90"
  7. tabindex="0"
  8. @click="close()"
  9. ></div>
  10. </div>
  11. </transition>
  12. <aside
  13. class="
  14. flex
  15. bg-primary
  16. w-96
  17. fixed
  18. top-0
  19. right-0
  20. z-30
  21. flex-col
  22. h-full
  23. max-w-full
  24. overflow-auto
  25. transition
  26. duration-300
  27. ease-in-out
  28. transform
  29. "
  30. :class="show ? 'shadow-xl translate-x-0' : 'translate-x-full'"
  31. >
  32. <slot name="content"></slot>
  33. </aside>
  34. </div>
  35. </template>
  36. <script setup lang="ts">
  37. import { onMounted, watch } from "@nuxtjs/composition-api"
  38. const props = defineProps<{
  39. show: Boolean
  40. }>()
  41. const emit = defineEmits<{
  42. (e: "close"): void
  43. }>()
  44. watch(
  45. () => props.show,
  46. (show) => {
  47. if (process.client) {
  48. if (show) document.body.style.setProperty("overflow", "hidden")
  49. else document.body.style.removeProperty("overflow")
  50. }
  51. }
  52. )
  53. onMounted(() => {
  54. document.addEventListener("keydown", (e) => {
  55. if (e.keyCode === 27 && props.show) close()
  56. })
  57. })
  58. const close = () => {
  59. emit("close")
  60. }
  61. </script>