2
0
mirror of https://github.com/tenrok/vue-context.git synced 2026-05-24 19:14:04 +03:00
This commit is contained in:
rawilk
2020-08-30 12:23:28 -05:00
parent aa8527325d
commit b5e5c320c2
13 changed files with 465 additions and 1 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ overridden by your own styles.
<br><br>
The menu disappears when you expect by utilizing `vue-clickaway` and it also optionally disappears when clicked on.
![Screenshot](screenshot.jpg)
![Screenshot](docs/images/screenshot.jpg)
## Getting Started
+4
View File
@@ -0,0 +1,4 @@
---
title: Api
sort: 3
---
+35
View File
@@ -0,0 +1,35 @@
---
title: Vue-Context
sort: 1
---
## Slots
| Slot | Description |
| --- | --- |
| default | The default slot also serves as a scoped slot which receives any data passed to the menu |
## Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `closeOnClick` | Boolean | `true` | If set to `false`, context menu will not automatically close when clicked on |
| `closeOnScroll` | Boolean | `true` | If set to `true`, context menu will automatically close on window scroll |
| `lazy` | Boolean | `false` | If set to `true`, context menu will be rendered with a `v-if` instead of `v-show` |
| `itemSelector` | Array, String | `['.v-context-item', '.v-context > li > a']` | The selector of the menu items the menu will use to look for to set accessibility attributes and for keyboard navigation. |
| `role` | String | `menu` | Used for the `role` attribute on the context menu |
| `subMenuOffset` | Number | `10` | Specify the offset in pixels of the submenus |
| `tag` | String | `ul` | Used as the root element of the context menu |
| `heightOffset` | Number | `25` | Specify distance from the menu to top/bottom of screen |
| `widthOffset` | Number | `25` | Specify distance from menu to left of screen |
| `useScrollHeight` | Boolean | `false` | Use the menu's scroll height instead of offset height to calculate positioning |
| `useScrollWidth` | Boolean | `false` | Use the menu's scroll width instead of offset width to calculate positioning |
## Events
| Event | Arguments | Description |
| --- | --- | --- |
| `close` | none | Emits when the context menu is closed |
| `open` | `event`, `data`, `top`, `left` | Emits when the menu is opened. the event, context menu data, top and left position are all sent through as parameters |
[View source](https://github.com/rawilk/vue-context/blob/master/src/js/vue-context.vue)
+6
View File
@@ -0,0 +1,6 @@
---
title: Changelog
sort: 4
---
All notable changes for laravel-breadcrumbs are documented [on Github](https://github.com/rawilk/vue-context/blob/master/CHANGELOG.md).
+4
View File
@@ -0,0 +1,4 @@
---
title: Demos
sort: 2
---
+4
View File
@@ -0,0 +1,4 @@
---
title: Basic Usage
sort: 1
---

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

+75
View File
@@ -0,0 +1,75 @@
---
title: Quickstart
sort: 2
---
## Installation
vue-context can be installed via npm:
```bash
npm i vue-context
```
## Usage
Import the component and use it in your app.
```js
import Vue from 'vue';
import VueContext from 'vue-context';
new Vue({
components: {
VueContext,
},
methods: {
onClick(text) {
alert(`You clicked ${text}!`);
}
}
}).$mount('#app');
```
For styling, you will need to import the component's styles into your own stylesheets, or into your JavaScript.
It's recommended to import into a stylesheet, however. If you are using sass, you can do the following:
```css
@import '~vue-context/src/sass/vue-context';
// Or
// @import '~vue-context/dist/css/vue-context.css';
```
Now 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>
<vue-context ref="menu">
<li>
<a @click.prevent="onClick($event.target.innerText)">Option 1</a>
</li>
<li>
<a @click.prevent="onClick($event.target.innerText)">Option 2</a>
</li>
</vue-context>
</div>
```
`@contextmenu.prevent` is the event listener needed to open the context menu. It is using `.prevent` as a modifier
to prevent the default behavior. In this example, the context menu 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 via an alert.
{.tip}
> The context menu defaults to a `<ul>` tag. For best results, make each menu item an `<a>` tag wrapped inside
> of an `<li>` tag.
+21
View File
@@ -0,0 +1,21 @@
---
title: Introduction
sort: 1
---
## Introduction
`vue-context` provides a simple yet flexible context menu for Vue. It is styled for the standard `<ul>` tag, but any menu
template can be used. The menu is lightweight with its only dependency being `vue-clickaway`. The menu has some basic
styles applied to it, but they can be easily overridden by your own styles.
The menu disappears when you expect by utilizing `vue-clickaway` and it also optionally disappears when clicked on.
![vue-context screenshot](../images/screenshot.jpg)
By default, the menu is set up to use a `<ul>` tag for the menu, which is given the attribute `role="menu"` automatically.
The component will also automatically apply the attribute `role="menuitem"` to each menu item when the context menu is opened.
## License
`vue-context` uses the MIT License (MIT). Please see the [license file](https://github.com/rawilk/vue-context/blob/master/LICENSE) for more information.
+9
View File
@@ -0,0 +1,9 @@
---
title: Questions & Issues
sort: 3
---
Find yourself stuck using the package? Found a bug? Do you have general questions or suggestions for improving the package?
Feel free to [create an issue on Github](https://github.com/rawilk/vue-context/issues) and I'll try to address it as soon as possible.
If you've found a bug regarding security please email [randall@randallwilk.dev](mailto:randall@randallwilk.dev) instead of using the issue tracker.
+4
View File
@@ -0,0 +1,4 @@
---
title: Usage
sort: 1
---
+255
View File
@@ -0,0 +1,255 @@
---
title: Advanced Usage
sort: 2
---
## Scoped Slot
To pass any data from the `contextmenu` event to your template, you can pass it as the second parameter of the `open` event
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
<template>
<div>
<p @contextmenu.prevent="$refs.menu.open($event, { foo: 'bar' })">
Right click on me
</p>
<vue-context ref="menu">
<template slot-scope="child">
<li>
<a @click.prevent="onClick($event.target.innerText, child.data)">
Option 1
</a>
</li>
<li>
<a @click.prevent="onClick($event.target.innerText, child.data)">
Option 2
</a>
</li>
</template>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext },
methods: {
onClick (text, data) {
alert(`You clicked "${text}"!`);
console.log(data);
// => { foo: 'bar' }
}
}
};
</script>
```
## Props
There are six props available on the context menu:
- `closeOnClick`
- `closeOnScroll`
- `lazy`
- `itemSelector`
- `role`
- `tag`
All props are optional. It is **not recommended** to use anything other than `ul` as a value for the tag property. If
you do choose a different tag, be sure to update the `itemSelector` prop accordingly to ensure proper keyboard navigation
can be used and the accessiblity attributes can be added to each menu item.
```html
<template>
<div>
<p @contextmenu.prevent="$refs.menu.open($event)">
Right click on me
</p>
<vue-context ref="menu"
:close-on-click="closeOnClick"
:close-on-scroll="closeOnScroll"
:lazy="lazy"
:role="role"
:tag="tag"
:item-selector="itemSelector"
>
<li>
<a class="custom-item-class">Option 1</a>
</li>
<li>
<a class="custom-item-class">Option 2</a>
</li>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext },
data () {
return {
// when set to true, the context menu will close when clicked on
closeOnClick: true,
// when set to true, the context menu will close when the window is scrolled
closeOnScroll: true,
// When false, the context menu is shown via v-show and will always be present in the DOM
lazy: false,
// The `role` attribute on the menu. Recommended to stay as `menu`
role: 'menu',
// The root html tag of the menu. Recommended to stay as `ul`
tag: 'ul',
// This is how the component is able to find each menu item. Useful if you use non-recommended markup
itemSelector: ['.custom-item-class']
};
}
};
</script>
```
## Events
There are two events emitted by the context menu:
- `close`
- `open`
The `close` event receives no parameters and is emitted when the context menu is closed.
The `open` event is emitted when the context menu is shown and receives the following parameters:
- `event`: The event that triggered the menu opening
- `data`: Any data passed to the menu from the trigger element.
- `top`: The top (y) position of the menu.
- `left`: The left (x) position of the menu.
```html
<template>
<div>
<p @contextmenu.prevent="$refs.menu.open($event, { foo: 'bar' })">
Right click on me
</p>
<vue-context ref="menu" @close="onClose" @open="onOpen">
<li>
<a>Option 1</a>
</li>
<li>
<a>Option 2</a>
</li>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext },
methods: {
onClose () {
console.log('The context menu was closed');
},
onOpen (event, data, top, left) {
console.log('The context menu was opened');
console.log(event, data, top, left);
}
}
};
</script>
```
## Left Click
If you want to use a _left_ click to open the menu instead, just replace `@contextmenu.prevent` with `@click.prevent`
as your event listener. If you have issues with the menu closing right after you click on your target element, you
probably just need to append the `stop` modifier onto the click event. See [issue #14](https://github.com/rawilk/vue-context/issues/14) for more information.
```html
<template>
<div>
<p @click.prevent="$refs.menu.open($event)">
Right click on me
</p>
<vue-context ref="menu">
<li>
<a>Option 1</a>
</li>
<li>
<a>Option 2</a>
</li>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext }
};
</script>
```
## Nested Menus
Nested context menus are possible by adding the class `v-context__sub` to a child `<li>` element in the menu.
Inside the `v-context__sub` element a new container (e.g. a `<ul>` element) with the class `v-context` must be created.
The nested `v-context` container will be opened and positioned after the `v-context__sub` element is hovered or
the menu element is expanded by keyboard right click.
There is no limit on how far you can nest the menus, the only requirement is to use the proper classes on each nested menu.
```html
<template>
<div>
<p @click.prevent="$refs.menu.open($event)">
Right click on me
</p>
<vue-context ref="menu">
<li>
<a>Not nested</a>
</li>
<li class="v-context__sub">
<a>Has nested menu</a>
<ul class="v-context">
<li>
<a>Nested menu item</a>
</li>
</ul>
</li>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext }
};
</script>
```
+47
View File
@@ -0,0 +1,47 @@
---
title: Basic Usage
sort: 1
---
Using the menu requires very little setup as shown below.
To use the context menu, you need to import it into your component and then create a trigger element to open the
context menu on.
```html
<template>
<div>
<p @contextmenu.prevent="$refs.menu.open">
Right click on me
</p>
<vue-context ref="menu">
<li>
<a @click.prevent="onClick($event.target.innerText)">
Option 1
</a>
</li>
<li>
<a @click.prevent="onClick($event.target.innerText)">
Option 2
</a>
</li>
</vue-context>
</div>
</template>
<script>
import VueContext from 'vue-context';
import 'vue-context/src/sass/vue-context.scss'; // Alternatively import into a stylesheet instead
export default {
components: { VueContext },
methods: {
onClick (text) {
alert(`You clicked "${text}"!`);
}
}
};
</script>
```