JSFiddle - React, Tailwind, and code Playground

by ChangJoo Park

HTML

<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>

<div id="app">
  <div class="message-wrapper">
    <div v-for="message in messages" class="message-item">
      {{message}}
    </div>    
  </div>
  
  <context-menu ref="contextMenu"></context-menu>
</div>

<template id="context-menu">
  <div class="context-menu" v-if="isOpen">
    <div v-for="item in items" class="context-menu-item">
      {{item}}
    </div>
  </div>
</template>

CSS

html, body {
  box-sizing: border-box;
  user-select: none;
}
.message-item {
  padding: 20px;
  border-bottom: 1px solid tomato;
  border-left: 1px solid tomato;
  border-right: 1px solid tomato;
  cursor: pointer;
}

.message-item:first-child {
  border-top: 1px solid tomato;
}

.context-menu {
  border: 1px solid orange;
  display: inline-block;
  position: absolute;
  width: 100px;
}

.context-menu-item {
  text-align: center;
  padding: 3px;
  border-bottom: 1px solid orange;
  cursor: pointer;
}
.context-menu-item:last-child {
  border-bottom: none;
}

JavaScript

function getPosition(e) {
  var posx = 0;
  var posy = 0;

  if (!e) var e = window.event;

  if (e.pageX || e.pageY) {
    posx = e.pageX;
    posy = e.pageY;
  } else if (e.clientX || e.clientY) {
    posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
  }

  return {
    x: posx,
    y: posy
  }
}

Vue.component('context-menu', {
	template: '#context-menu',
  data: function () {
  	return {
    	isOpen: false,
    	items: ['A', 'B', 'C', 'D']
    }
	}
})
new Vue ({
	el: '#app',
  mounted: function () {
  	var item = document.querySelector('.message-wrapper');
    console.log(item);
  	item.addEventListener('contextmenu', function (event) {
	    event.preventDefault();
      var contextMenuComponent = this.$refs.contextMenu;
      var contextMenuDOM = contextMenuComponent.$el;
      var menuWidth = contextMenuDOM.clientWidth;
      var menuHeight = contextMenuDOM.clientHeight;
			contextMenuComponent.$data.isOpen = true;
      var position = getPosition(event);
			console.log(position);
			console.log(contextMenuDOM.style);      
		}.bind(this));
	},
  data: function () {
  	return {
    	messages: [
      	'Hello - A',
      	'Hello - B',
      	'Hello - C',
      	'Hello - D',
      	'Hello - E'
      ]
    }
  }
})