CustomDrawer.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <template>
  2. <div class="bg-red">
  3. <div class="drawer"
  4. :dir="directionBasedOnSideSelection()"
  5. :class="{ 'is-open': isOpen, 'is-visible': isVisible }">
  6. <!-- "we don't use drawer__overlay" -->
  7. <!-- <div-->
  8. <!-- class="drawer__overlay"-->
  9. <!-- :style="{-->
  10. <!-- maxWidth: maxWidth,-->
  11. <!-- transitionDuration: `${speed}ms`-->
  12. <!-- }"-->
  13. <!-- ></div>-->
  14. <div class="drawer__content"
  15. :dir="directionBasedOnSideSelection('content')"
  16. :style="{
  17. transform: `translateX(${transformValue})`,
  18. maxWidth: maxWidth,
  19. transitionDuration: `${speed}ms`,
  20. background: backgroundColor,
  21. }">
  22. <!--v-click-away="closeDrawer"-->
  23. <slot />
  24. </div>
  25. </div>
  26. </div>
  27. </template>
  28. <script>
  29. // import { directive } from 'vue3-click-away'
  30. export default {
  31. name: 'CustomDrawer',
  32. // directives: {
  33. // ClickAway: directive
  34. // },
  35. props: {
  36. side: {
  37. type: String,
  38. default: 'right'
  39. },
  40. isOpen: {
  41. type: Boolean,
  42. required: false,
  43. default: false
  44. },
  45. isExpanded: {
  46. type: Boolean,
  47. required: false,
  48. default: false
  49. },
  50. maxWidth: {
  51. type: String,
  52. required: false,
  53. default: '400px'
  54. },
  55. expansionValue: {
  56. type: String,
  57. required: false,
  58. default: undefined
  59. },
  60. // Transition Speed in Milliseconds
  61. speed: {
  62. type: Number,
  63. required: false,
  64. default: 300
  65. },
  66. backgroundColor: {
  67. type: String,
  68. required: false,
  69. default: '#fafafa'
  70. }
  71. },
  72. data () {
  73. return {
  74. isVisible: false,
  75. isTransitioning: false,
  76. transformValue: '100%'
  77. }
  78. },
  79. computed: {
  80. },
  81. watch: {
  82. isExpanded() {
  83. this.transformValue = this.changeDrawerTransition(this.expansionValue)
  84. },
  85. isOpen (val) {
  86. this.isTransitioning = true
  87. if (val) {
  88. this.toggleBackgroundScrolling(true)
  89. this.transformValue = this.changeDrawerTransition(0)
  90. this.isVisible = true
  91. } else {
  92. this.toggleBackgroundScrolling(false)
  93. this.transformValue = this.changeDrawerTransition('100%')
  94. setTimeout(() => {
  95. this.isVisible = false
  96. }, this.speed)
  97. }
  98. setTimeout(() => (this.isTransitioning = false), this.speed)
  99. }
  100. },
  101. mounted () {
  102. this.transformValue = this.changeDrawerTransition(this.transformValue)
  103. this.isVisible = this.isOpen
  104. },
  105. methods: {
  106. toggleBackgroundScrolling (enable) {
  107. const body = document.querySelector('body')
  108. body.style.overflow = enable ? 'hidden' : null
  109. },
  110. changeDrawerTransition(value) {
  111. if (this.side === 'right') {
  112. return '-' + value
  113. }
  114. return value
  115. },
  116. directionBasedOnSideSelection (mode) {
  117. if (mode === 'content') {
  118. return 'rtl'
  119. }
  120. if (this.side === 'right') {
  121. return 'rtl'
  122. }
  123. return 'ltr'
  124. }
  125. // closeDrawer() {
  126. // console.log('closeDrawer')
  127. // if (!this.isTransitioning) {
  128. // this.$emit('close')
  129. // }
  130. // }
  131. }
  132. }
  133. </script>
  134. <style lang="scss" scoped>
  135. .drawer {
  136. visibility: hidden;
  137. &.is-visible {
  138. visibility: visible;
  139. }
  140. &.is-open {
  141. //.drawer__overlay {
  142. // opacity: 0.5;
  143. //}
  144. .drawer__content {
  145. z-index: 100000;
  146. //transform: translateX(0);
  147. }
  148. }
  149. &__overlay {
  150. position: fixed;
  151. top: 0;
  152. right: 0;
  153. bottom: 0;
  154. left: 0;
  155. width: 100%;
  156. z-index: 200;
  157. opacity: 0;
  158. transition-property: opacity;
  159. //background-color: #000000;
  160. user-select: none;
  161. }
  162. &__content {
  163. position: fixed;
  164. top: 0;
  165. right: 0;
  166. bottom: 0;
  167. height: 100%;
  168. width: 100%;
  169. z-index: 2000;
  170. overflow: auto;
  171. transition-property: transform;
  172. display: flex;
  173. flex-direction: column;
  174. //transform: translateX(100%);
  175. box-shadow: 0 2px 6px #777;
  176. }
  177. }
  178. </style>