2
0
mirror of https://github.com/tenrok/vue-context.git synced 2026-06-23 13:00:32 +03:00

Code restructure (#1)

This commit is contained in:
Randall Wilk
2018-05-26 11:43:23 -05:00
committed by GitHub
parent a521b025c2
commit 3116d06d77
17 changed files with 14548 additions and 245 deletions
+4
View File
@@ -0,0 +1,4 @@
node_modules/
.idea
npm-debug.log*
**/mix-manifest.json
+6
View File
@@ -0,0 +1,6 @@
docs/
src/
test/
build/
.idea
**/mix-manifest.json
+8 -1
View File
@@ -1,9 +1,16 @@
# Changelog # Changelog
### 3.0.0 (May 26, 2018)
- Update dependencies
- Update documentation
- Update code structure and build process
- **Breaking** Change slot scope definition from `userData` to just `data`
- **Breaking** Component gets imported as `{ VueContext }` instead of `VContext` now
### 2.0.1 (Aug 18, 2017) ### 2.0.1 (Aug 18, 2017)
- Removed bottom border from context menu line items. - Removed bottom border from context menu line items.
- Added license file - Added license file
- Created changelog file - Created changelog file
### 2.0.0 (Aug 17, 2017) ### 2.0.0 (Aug 17, 2017)
- Initial Release - Initial Re-Release
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2017 Randall Wilk Copyright (c) 2018 Randall Wilk
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+91 -78
View File
@@ -3,15 +3,22 @@
[![npm](https://img.shields.io/npm/v/vue-context.svg)](https://www.npmjs.org/package/vue-context) [![npm](https://img.shields.io/npm/v/vue-context.svg)](https://www.npmjs.org/package/vue-context)
[![npm](https://img.shields.io/npm/dt/vue-context.svg)](https://www.npmjs.org/package/vue-context) [![npm](https://img.shields.io/npm/dt/vue-context.svg)](https://www.npmjs.org/package/vue-context)
A simple yet flexible context menu component for Vue. It is styled for the standard `ul` tag, but any menu template can be used. A simple yet flexible context menu for Vue. It is styled for the standard `ul` tag,
The only dependency this package has is Vue, so the majority of styling is up to you, and any package styles for the menu but any menu template can be used. The only dependency this package has is Vue,
so the majority of styling is up to you, and any package styles for the menu
can easily be overridden. can easily be overridden.
The menu disappears when you expect by using the `onblur` event and also disappears when clicked on. The menu disappears when you expect by using the `onblur` even and it also
disappears when clicked on.
## Note
The API has changed. Check [v2.0.1 documentation](https://github.com/rawilk/vue-context/blob/master/docs/2.0.1.md)
if you use the old version.
## Getting Started ## Getting Started
The following instructions will help you get the vue-context menu up and running on your project. The following instructions will help you get the vue-context menu up and running on
your project.
### Installation ### Installation
@@ -22,111 +29,117 @@ $ npm install vue-context --save
## Basic Usage ## Basic Usage
Import the package and use in your Vue instance, and add a simple method for the click event. Import the package and use it in your Vue instance, and add a simple method
for the click event.
```js ```js
import Vue from 'vue'; import Vue from 'vue';
import vContext from 'vue-context'; import { VueContext } from 'vue-context';
new Vue({ new Vue({
el: '#app', components: {
components: { VueContext
vContext },
},
methods: { methods: {
/** /**
* Alert the text of the menu item clicked on. * Alert the text of the menu item that was clicked on.
* *
* @param text * @param {string} text
*/ */
onClick(text) { onClick (text) {
alert(`You clicked ${text}!`); alert(`You clicked ${text}!`);
} }
} }
}); }).$mount('#app');
``` ```
Add an element to the page that will trigger the context menu to appear, and also add the context menu to the page. Add an element to the page that will trigger the context menu to appear,
and also add the context menu to the page.
```html ```html
<div id="app"> <div id="app">
<div> <div>
<p @contextmenu.prevent="$refs.menu.open"> <p @contextmenu.prevent="$refs.menu.open">
Right click on me Right click on me
</p> </p>
</div> </div>
<v-context ref="menu"> <vue-context ref="menu">
<ul> <ul>
<li @click="onClick($event.target.innerText)">Option 1</li> <li @click="onClick($event.target.innerText)">Option 1</li>
<li @click="onClick($event.target.innerText)">Option 2</li> <li @click="onClick($event.target.innerText)">Option 2</li>
</ul> </ul>
</v-context> </vue-context>
</div> </div>
``` ```
`@contextmenu.prevent` is the event listener needed to open the context menu. It is using `.prevent` as a modifier to prevent the `@contextmenu.prevent` is the event listener needed to open the context menu. It is using
the default behavior. It has a ref of `menu`, which is what `$refs.menu` is referring to. When each item is clicked on, the text of `.prevent` as a modifier to prevent the default behavior. It has a ref of `menu`, which
the item is sent to the `onClick` method on the Vue instance, which is then shown in an alert. is what `$refs.menu` is referring to. When each item is clicked on, the text of the item
is sent to the `onClick` method on the Vue instance, which is then shown in an alert.
## Advanced Usage ## Advanced Usage
To pass any data from the `contextmenu` event to your template, you can pass it as the second parameter of `open` and To pass any data from the `contextmenu` event to your template, you can pass it as the second
access it within a [scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots) under the `userData` property. parameter of `open` and access it within a [scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots)
under the `data` property`. `$event` must be passed as the first parameter,
otherwise the context menu will not function properly.
```html ```html
<div id="app"> <div id="app">
<p @contextmenu.prevent="$refs.menu.open($event, 'foo')"> <p @contextmenu.prevent="$refs.menu.open($event, { foo: 'bar' })">
Right click on me Right click on me
</p> </p>
<v-context ref="menu"> <vue-context ref="menu">
<template scope="child"> <ul slot-scope="child">
<ul> <li @click="onClick($event.target.innerText, child.data)">Option 1</li>
<li @click="onClick($event.target.innerText, child.userData)">Option 1</li> <li @click="onClick($event.target.innerText, child.data)">Option 2</li>
<li @click="onClick($event.target.innerText, child.userData)">Option 2</li> </ul>
</ul> </vue-context>
</template>
</v-context>
</div> </div>
``` ```
Now the `onClick` method on the Vue instance has access to any user data passed to it, which in this case this the string `foo`. The Now the `onClick` method on the Vue instance has access to any user data passed to it,
`userData` can also be used to output dynamic content to the context menu. which in this case is an object with a property named `foo`. The `data` slot scope
can also be used to output dynamic content to the context menu.
```js ```js
import Vue from 'vue'; import Vue from 'vue';
import vContext from 'vue-context'; import { VueContext } from 'vue-context';
new Vue({ new Vue({
el: '#app', components: {
components: { VueContext
vContext },
},
methods: { methods: {
/** /**
* Alert the text of the menu item clicked on. Console log the data sent from the menu. * Alert the text of the menu item that was clicked on.
* * Console log the data sent from the menu.
* @param text *
* @param userData * @param {string} text
*/ * @param {object} data
onClick(text, userData) { */
alert(`You clicked ${text}!`); onClick (text, data) {
console.log(userData); alert(`You clicked ${text}!`);
} console.log(data);
} // => { foo: 'bar' }
}); }
}
}).$mount('#app');
``` ```
## Credits ## Credits
vue-context is inspired from [vue-lil-context-menu](https://github.com/timwis/vue-lil-context-menu) vue-context is inspired from [vue-lil-context-menu](https://github.com/timwis/vue-lil-context-menu)
and [Vue.JS Right Click Menu](http://vuejsexamples.com/vue-js-right-click-menu/). Ultimately vue-context is intended and [Vue.JS Right Click Menu](http://vuejsexamples.com/vue-js-right-click-menu/). Ultimately
to provide a simple and lightweight context menu for Vue. vue-context is intended to provide a simple and lightweight context menu for Vue.
## License ## License
+6
View File
@@ -0,0 +1,6 @@
const { mix } = require('laravel-mix');
mix
.setPublicPath('test/js/dist')
.js('test/js/src/index.js', 'index.js')
.sourceMaps();
+14
View File
@@ -0,0 +1,14 @@
const { mix } = require('laravel-mix');
const inProduction = mix.inProduction();
mix
.setPublicPath('dist')
.js('src/index.js', 'vue-context.js')
.sourceMaps(! inProduction)
.webpackConfig({
output: {
libraryTarget: 'umd',
umdNamedDefine: true
}
});
+1
View File
File diff suppressed because one or more lines are too long
+135
View File
@@ -0,0 +1,135 @@
# vue-context
A simple yet flexible context menu component for Vue. It is styled for the standard `ul` tag, but any menu template can be used.
The only dependency this package has is Vue, so the majority of styling is up to you, and any package styles for the menu
can easily be overridden.
The menu disappears when you expect by using the `onblur` event and also disappears when clicked on.
## Note
This documentation is for version 2.0.1 of vue-context. For the most up-to-date version
of the package and documentation, please visit [vue-context](https://github.com/rawilk/vue-context).
## Getting Started
The following instructions will help you get the vue-context menu up and running on your project.
### Installation
Using npm:
```bash
$ npm install vue-context@2.0.1 --save
```
## Basic Usage
Import the package and use in your Vue instance, and add a simple method for the click event.
```js
import Vue from 'vue';
import vContext from 'vue-context';
new Vue({
el: '#app',
components: {
vContext
},
methods: {
/**
* Alert the text of the menu item clicked on.
*
* @param text
*/
onClick(text) {
alert(`You clicked ${text}!`);
}
}
});
```
Add an element to the page that will trigger the context menu to appear, and also add the context menu to the page.
```html
<div id="app">
<div>
<p @contextmenu.prevent="$refs.menu.open">
Right click on me
</p>
</div>
<v-context ref="menu">
<ul>
<li @click="onClick($event.target.innerText)">Option 1</li>
<li @click="onClick($event.target.innerText)">Option 2</li>
</ul>
</v-context>
</div>
```
`@contextmenu.prevent` is the event listener needed to open the context menu. It is using `.prevent` as a modifier to prevent the
the default behavior. It has a ref of `menu`, which is what `$refs.menu` is referring to. When each item is clicked on, the text of
the item is sent to the `onClick` method on the Vue instance, which is then shown in an alert.
## Advanced Usage
To pass any data from the `contextmenu` event to your template, you can pass it as the second parameter of `open` and
access it within a [scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots) under the `userData` property.
```html
<div id="app">
<p @contextmenu.prevent="$refs.menu.open($event, 'foo')">
Right click on me
</p>
<v-context ref="menu">
<template scope="child">
<ul>
<li @click="onClick($event.target.innerText, child.userData)">Option 1</li>
<li @click="onClick($event.target.innerText, child.userData)">Option 2</li>
</ul>
</template>
</v-context>
</div>
```
Now the `onClick` method on the Vue instance has access to any user data passed to it, which in this case this the string `foo`. The
`userData` can also be used to output dynamic content to the context menu.
```js
import Vue from 'vue';
import vContext from 'vue-context';
new Vue({
el: '#app',
components: {
vContext
},
methods: {
/**
* Alert the text of the menu item clicked on. Console log the data sent from the menu.
*
* @param text
* @param userData
*/
onClick(text, userData) {
alert(`You clicked ${text}!`);
console.log(userData);
}
}
});
```
## Credits
vue-context is inspired from [vue-lil-context-menu](https://github.com/timwis/vue-lil-context-menu)
and [Vue.JS Right Click Menu](http://vuejsexamples.com/vue-js-right-click-menu/). Ultimately vue-context is intended
to provide a simple and lightweight context menu for Vue.
## License
MIT
-131
View File
@@ -1,131 +0,0 @@
<template>
<div
v-show="show"
class="v-context"
:style="style"
tabindex="-1"
@blur="close"
@click="close"
@contextmenu.capture.prevent
>
<slot :userData="userData"></slot>
</div>
</template>
<script>
import Vue from 'vue';
export default {
data() {
return {
top: null,
left: null,
userData: null,
show: false
};
},
computed: {
/**
* Get the position of the context menu.
*/
style() {
return this.show
? { top: `${this.top}px`, left: `${this.left}px` }
: {};
}
},
methods: {
/**
* Close the menu.
*/
close() {
this.top = null;
this.left = null;
this.userData = null;
this.show = false;
},
/**
* Open the menu.
*
* @param event
* @param userData
*/
open(event, userData) {
this.userData = userData;
let top = event.clientY,
left = event.clientX;
this.show = true;
Vue.nextTick(() => {
this.setMenu(top, left);
this.$el.focus();
});
},
/**
* Set menu coordinates.
*
* @param top
* @param left
*/
setMenu(top, left) {
let largestHeight = window.innerHeight - this.$el.offsetHeight - 25;
let largestWidth = window.innerWidth - this.$el.offsetWidth - 25;
if (top > largestHeight) {
top = largestHeight;
}
if (left > largestWidth) {
left = largestWidth;
}
this.top = top;
this.left = left;
}
}
}
</script>
<style lang="scss" scoped>
$blue600: #1e88e5;
$gray74: #bdbdbd;
$gray93: #ededed;
$gray98: #fafafa;
.v-context {
background: $gray98;
border: 1px solid $gray74;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
display: block;
margin: 0;
padding: 0;
position: fixed;
width: 250px;
z-index: 99999;
& ul {
list-style: none;
padding-left: 0;
padding-top: 10px;
padding-bottom: 10px;
margin: 0;
font-size: 12px;
font-weight: 600;
& li {
margin: 0;
padding: 10px 35px;
cursor: pointer;
&:hover {
background: $blue600;
color: $gray98;
}
}
}
}
</style>
+13914
View File
File diff suppressed because it is too large Load Diff
+23 -34
View File
@@ -1,48 +1,37 @@
{ {
"name": "vue-context", "name": "vue-context",
"version": "2.0.1", "version": "3.0.0",
"description": "A simple vue context menu component.", "description": "A simple vue context menu component.",
"main": "index.vue", "main": "dist/vue-context.js",
"repository": {
"type": "git",
"url": "https://github.com/rawilk/vue-context"
},
"scripts": { "scripts": {
"dev": "npm run development", "dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --env.mixfile=build/webpack.mix.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"development": "cross-env NODE_ENV=development webpack --progress", "dev-test": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --env.mixfile=build/webpack-test.mix.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "npm run development -- --watch", "watch-test": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --env.mixfile=build/webpack-test.mix.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production", "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --env.mixfile=build/webpack.mix.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
"production": "cross-env NODE_ENV=production webpack --progress"
}, },
"keywords": [ "keywords": [
"vue", "Vue",
"Vue2",
"context", "context",
"menu", "context menu"
"vue2"
], ],
"repository": {
"type": "git",
"url": "git+https://github.com/rawilk/vue-context.git"
},
"author": "Randall Wilk <randall@randallwilk.com>", "author": "Randall Wilk <randall@randallwilk.com>",
"license": "MIT", "license": "MIT",
"bugs": {
"url": "https://github.com/rawilk/vue-context/issues"
},
"homepage": "https://github.com/rawilk/vue-context#readme",
"dependencies": { "dependencies": {
"vue": "^2.4.2" "vue": "^2.5.16"
}, },
"devDependencies": { "devDependencies": {
"babel-cli": "^6.26.0", "babel-preset-env": "^1.7.0",
"babel-core": "^6.26.0", "cross-env": "^5.1.6",
"babel-loader": "^7.1.1", "laravel-mix": "^2.1.11",
"babel-preset-es2015": "^6.24.1", "node-sass": "^4.9.0"
"cross-env": "^5.0.5", }
"css-loader": "^0.28.5",
"extract-text-webpack-plugin": "^3.0.0",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"style-loader": "^0.18.2",
"vue-loader": "^13.0.4",
"vue-template-compiler": "^2.4.2",
"webpack": "^3.5.5"
},
"files": [
"index.vue",
"package.json",
"README.md"
]
} }
+3
View File
@@ -0,0 +1,3 @@
import VueContext from './vue-context';
export { VueContext };
+126
View File
@@ -0,0 +1,126 @@
<template>
<div class="v-context"
v-show="show"
:style="style"
tabindex="-1"
@blur="close"
@click="close"
@contextmenu.capture.prevent
>
<slot :data="data"></slot>
</div>
</template>
<script>
export default {
computed: {
/**
* Generate the CSS styles for positioning the context menu.
*
* @returns {object|null}
*/
style () {
return this.show
? { top: `${this.top}px`, left: `${this.left}px` }
: null;
},
},
data () {
return {
top: null,
left: null,
show: false,
data: null
};
},
methods: {
/**
* Close the context menu.
*/
close () {
this.top = null;
this.left = null;
this.data = null;
this.show = false;
},
/**
* Open the context menu.
*
* @param {Event} event
* @param {object} data
*/
open (event, data) {
this.data = data;
this.show = true;
this.$nextTick(() => {
this.positionMenu(event.clientY, event.clientX);
this.$el.focus();
});
},
/**
* Set the context menu top and left positions.
*
* @param {number} top
* @param {number} left
*/
positionMenu (top, left) {
const largestHeight = window.innerHeight - this.$el.offsetHeight - 25;
const largestWidth = window.innerWidth - this.$el.offsetWidth - 25;
if (top > largestHeight) {
top = largestHeight;
}
if (left > largestWidth) {
left = largestWidth;
}
this.top = top;
this.left = left;
}
},
};
</script>
<style lang="scss" scoped>
$blue600: #1e88e5;
$gray74: #bdbdbd;
$gray93: #ededed;
$gray98: #fafafa;
.v-context {
background: $gray98;
border: 1px solid $gray74;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
display: block;
margin: 0;
padding: 0;
position: fixed;
width: 250px;
z-index: 99999;
ul {
list-style: none;
padding: 10px 0;
margin: 0;
font-size: 12px;
font-weight: 600;
li {
margin: 0;
padding: 10px 35px;
cursor: pointer;
&:hover {
background: $blue600;
color: $gray98;
}
}
}
}
</style>
+23
View File
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue Context Test Page</title>
</head>
<body>
<div id="app">
<p @contextmenu.prevent="$refs.menu.open($event, { foo: 'bar' })">
Right click on me
</p>
<vue-context ref="menu">
<ul slot-scope="child">
<li @click="onClick(child.data)">Option 1 {{ child.data && child.data.foo }}</li>
<li>Option 2</li>
</ul>
</vue-context>
</div>
<script src="js/dist/index.js"></script>
</body>
</html>
+179
View File
File diff suppressed because one or more lines are too long
+14
View File
@@ -0,0 +1,14 @@
import Vue from 'vue';
import { VueContext } from '../../../dist/vue-context';
new Vue({
components: {
VueContext
},
methods: {
onClick (data) {
console.log(data);
},
},
}).$mount('#app');