mirror of
https://github.com/tenrok/vue-context.git
synced 2026-06-07 21:52:24 +03:00
Release/v5 (#43)
This commit is contained in:
+2
-1
@@ -1,4 +1,5 @@
|
||||
node_modules/
|
||||
.idea
|
||||
npm-debug.log*
|
||||
**/mix-manifest.json
|
||||
**/mix-manifest.json
|
||||
test/js/dist/
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
docs/
|
||||
src/
|
||||
test/
|
||||
build/
|
||||
.idea
|
||||
|
||||
+44
-26
@@ -2,12 +2,30 @@
|
||||
|
||||
All notable changes to this project will be documented here.
|
||||
|
||||
<a name="5.0.0"></a>
|
||||
## [5.0.0](https://github.com/rawilk/vue-context/releases/tag/5.0.0)
|
||||
|
||||
Released 2019-11-14
|
||||
|
||||
### Added
|
||||
- Add default export in entry point ([#41](https://github.com/rawilk/vue-context/issues/41)).
|
||||
- Add support for nested context menus ([#37](https://github.com/rawilk/vue-context/pull/37)).
|
||||
|
||||
### Changes
|
||||
- Update entry point to source ([#33](https://github.com/rawilk/vue-context/issues/33)).
|
||||
- No longer build component with webpack ([#33](https://github.com/rawilk/vue-context/issues/33)).
|
||||
- Component source is available through npm now, including the sass files.
|
||||
|
||||
### Release notes
|
||||
- Even though there shouldn't be any breaking changes in this release, it's a major release because
|
||||
breaking changes were introduced in version 4.1.0, which should have been a major release instead.
|
||||
|
||||
<a name="4.1.1"></a>
|
||||
## [4.1.1](https://github.com/rawilk/vue-context/releases/tag/4.1.1)
|
||||
|
||||
Released 2019-10-20
|
||||
|
||||
### Bug Fixes 4.1.1
|
||||
### Bug Fixes
|
||||
- Fix bug of "Unknown custom element" ([#40](https://github.com/rawilk/vue-context/issues/40)).
|
||||
|
||||
<a name="4.1.0"></a>
|
||||
@@ -15,10 +33,10 @@ Released 2019-10-20
|
||||
|
||||
Released 2019-10-11
|
||||
|
||||
### Breaking Changes 4.1.0
|
||||
### Breaking Changes
|
||||
- Move menu styles from js to its own stylesheet ([#36](https://github.com/rawilk/vue-context/issues/36))
|
||||
|
||||
### Changes 4.1.0
|
||||
### Changes
|
||||
- Remove core-js as a dependency in favor of local polyfills for a smaller build size ([#33](https://github.com/rawilk/vue-context/issues/33))
|
||||
|
||||
<a name="4.0.3"></a>
|
||||
@@ -26,10 +44,10 @@ Released 2019-10-11
|
||||
|
||||
Released 2019-07-28
|
||||
|
||||
### Bug Fixes 4.0.3
|
||||
### Bug Fixes
|
||||
- Make `localItemSelector` reactive to changes from `itemSelector` prop ([#30](https://github.com/rawilk/vue-context/issues/30)).
|
||||
|
||||
### Updates 4.0.3
|
||||
### Updates
|
||||
- Update dev dependencies
|
||||
|
||||
<a name="4.0.2"></a>
|
||||
@@ -37,7 +55,7 @@ Released 2019-07-28
|
||||
|
||||
Released 2019-06-22
|
||||
|
||||
### Bug Fixes 4.0.2
|
||||
### Bug Fixes
|
||||
- Fix menu item width issues ([#26](https://github.com/rawilk/vue-context/issues/26)).
|
||||
- Remove outline from menu and menu items when given focus ([#26](https://github.com/rawilk/vue-context/issues/26)).
|
||||
|
||||
@@ -46,7 +64,7 @@ Released 2019-06-22
|
||||
|
||||
Released 2019-06-03
|
||||
|
||||
### Bug Fixes 4.0.1
|
||||
### Bug Fixes
|
||||
- Always emit the close event on click. See issue [#23](https://github.com/rawilk/vue-context/issues/23)
|
||||
|
||||
<a name="4.0.0"></a>
|
||||
@@ -54,17 +72,17 @@ Released 2019-06-03
|
||||
|
||||
Released 2019-05-18
|
||||
|
||||
### Added 4.0.0
|
||||
### Added
|
||||
- Added support for keyboard navigation (up and down arrows).
|
||||
- Added ability to close menu on esc.
|
||||
- Added `lazy` prop as an alternative to `v-show`.
|
||||
- Added `tag` prop to specify menu tag (defaults to `<ul>`).
|
||||
|
||||
### Changes 4.0.0
|
||||
### Changes
|
||||
- Default menu tag is now `<ul>` and menu is now the top-level element.
|
||||
- Changed how the menu is styled.
|
||||
|
||||
### Updates 4.0.0
|
||||
### Updates
|
||||
- Updated build process and project structure.
|
||||
- Ran `npm audit fix` to fix vulnerabilities found from dependencies.
|
||||
|
||||
@@ -73,7 +91,7 @@ Released 2019-05-18
|
||||
|
||||
Released 2019-04-05
|
||||
|
||||
### Bug Fixes 3.4.2
|
||||
### Bug Fixes
|
||||
- Only add scroll event listener on `closeOnScroll` prop value change if the menu is open.
|
||||
|
||||
<a name="3.4.1"></a>
|
||||
@@ -81,7 +99,7 @@ Released 2019-04-05
|
||||
|
||||
Released 2019-04-03
|
||||
|
||||
### Updates 3.4.1
|
||||
### Updates
|
||||
- **Scroll Listener:** Only attach the close scroll event listener when opened and immediately remove it when menu is closed
|
||||
to prevent it being called unnecessarily.
|
||||
- **Dependencies:** Removed Vue as a dependency as it never really was one since v3.0.0.
|
||||
@@ -92,7 +110,7 @@ to prevent it being called unnecessarily.
|
||||
|
||||
Released 2018-11-19
|
||||
|
||||
### Bug fixes 3.4.0
|
||||
### Bug fixes
|
||||
- **Close event:** only emit the event if menu is actually open (fixes [#13](https://github.com/rawilk/vue-context/issues/13))
|
||||
|
||||
<a name="3.3.1"></a>
|
||||
@@ -100,10 +118,10 @@ Released 2018-11-19
|
||||
|
||||
Released 2018-10-23
|
||||
|
||||
### Changes 3.3.1
|
||||
### Changes
|
||||
- Context menu now closes via [clickaway](https://github.com/simplesmiler/vue-clickaway) instead of a blur event. Credit: [robjbrain](https://github.com/robjbrain)
|
||||
|
||||
### Updates 3.3.1
|
||||
### Updates
|
||||
- Updated vue and other dev dependencies.
|
||||
|
||||
<a name="3.3.0"></a>
|
||||
@@ -111,7 +129,7 @@ Released 2018-10-23
|
||||
|
||||
Released 2018-10-15
|
||||
|
||||
### Features 3.3.0
|
||||
### Features
|
||||
- **Events:** both open and close events are now emitted by the component. ([#10](https://github.com/rawilk/vue-context/issues/10))
|
||||
|
||||
<a name="3.2.0"></a>
|
||||
@@ -119,7 +137,7 @@ Released 2018-10-15
|
||||
|
||||
Released 2018-09-12
|
||||
|
||||
### Features 3.2.0
|
||||
### Features
|
||||
- **Close on click prop:** added a prop to prevent closing the context menu on click. ([#8](https://github.com/rawilk/vue-context/issues/8))
|
||||
|
||||
<a name="3.1.1"></a>
|
||||
@@ -127,7 +145,7 @@ Released 2018-09-12
|
||||
|
||||
Released 2018-06-23
|
||||
|
||||
### Updates 3.1.1
|
||||
### Updates
|
||||
- Updated README.md
|
||||
- Added code comments
|
||||
|
||||
@@ -136,7 +154,7 @@ Released 2018-06-23
|
||||
|
||||
Released 2018-05-29
|
||||
|
||||
### Features 3.1.0
|
||||
### Features
|
||||
- **Scroll prop:** added a prop to close the context menu automatically on window scroll. ([#2](https://github.com/rawilk/vue-context/issues/2))
|
||||
|
||||
<a name="3.0.2"></a>
|
||||
@@ -144,10 +162,10 @@ Released 2018-05-29
|
||||
|
||||
Released 2018-05-29
|
||||
|
||||
### Updates 3.0.2
|
||||
### Updates
|
||||
- Updated documentation
|
||||
|
||||
### Added 3.0.2
|
||||
### Added
|
||||
- Added [demos](https://vue-context.randallwilk.com) for the component.
|
||||
|
||||
<a name="3.0.0"></a>
|
||||
@@ -155,15 +173,15 @@ Released 2018-05-29
|
||||
|
||||
Released 2018-05-26
|
||||
|
||||
### Breaking changes 3.0.0
|
||||
### Breaking changes
|
||||
- Changed slot scope definition from `userData` to just `data`.
|
||||
- Component gets imported as `{ VueContext }` instead of `VContext` now.
|
||||
|
||||
### Updates 3.0.0
|
||||
### Updates
|
||||
- Updated dependencies
|
||||
- Updated documentation
|
||||
|
||||
### Changes 3.0.0
|
||||
### Changes
|
||||
- Changed code structure and build process.
|
||||
|
||||
<a name="2.0.1"></a>
|
||||
@@ -171,11 +189,11 @@ Released 2018-05-26
|
||||
|
||||
Released 2017-08-18
|
||||
|
||||
### Added 2.0.1
|
||||
### Added
|
||||
- License file
|
||||
- Changelog file
|
||||
|
||||
### Removed 2.0.1
|
||||
### Removed
|
||||
- Removed bottom border from context menu line items.
|
||||
|
||||
<a name="2.0.0"></a>
|
||||
|
||||
@@ -75,12 +75,22 @@ Next add an element to the page that will trigger the context menu to appear, an
|
||||
|
||||
```bash
|
||||
@import '~vue-context/dist/css/vue-context.css';
|
||||
|
||||
// Or
|
||||
@import '~vue-context/src/sass/vue-context';
|
||||
```
|
||||
|
||||
## Documentation/Demo
|
||||
|
||||
For full documentation and demos, go here: https://vue-context.com/docs
|
||||
|
||||
## Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute. [[Contribute]](CONTRIBUTING.md).
|
||||
|
||||
- [rawilk](https://github.com/rawilk)
|
||||
- [wol-soft](https://github.com/wol-soft)
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
const mix = require('laravel-mix');
|
||||
|
||||
mix
|
||||
.setPublicPath('dist/css')
|
||||
.sass('src/sass/vue-context.scss', 'vue-context.css');
|
||||
+2
-11
@@ -1,14 +1,5 @@
|
||||
const mix = require('laravel-mix');
|
||||
|
||||
const inProduction = mix.inProduction();
|
||||
|
||||
mix
|
||||
.setPublicPath('dist/js')
|
||||
.js('src/js/index.js', 'vue-context.js')
|
||||
.sourceMaps(! inProduction)
|
||||
.webpackConfig({
|
||||
output: {
|
||||
libraryTarget: 'umd',
|
||||
umdNamedDefine: true
|
||||
}
|
||||
});
|
||||
.setPublicPath('dist/css')
|
||||
.sass('src/sass/vue-context.scss', 'vue-context.css');
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
.v-context{background-color:#fff;background-clip:padding-box;border-radius:.25rem;border:1px solid rgba(0,0,0,.15);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);display:block;margin:0;padding:10px 0;min-width:10rem;z-index:1500;position:fixed;list-style:none;box-sizing:border-box}.v-context>li{margin:0}.v-context>li>a{display:block;padding:.5rem 1.5rem;font-weight:400;color:#212529;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.v-context>li>a:focus,.v-context>li>a:hover{text-decoration:none;color:#212529;background-color:#f8f9fa}.v-context:focus,.v-context>li>a:focus{outline:0}
|
||||
.v-context,.v-context ul{background-color:#fff;background-clip:padding-box;border-radius:.25rem;border:1px solid rgba(0,0,0,.15);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);display:block;margin:0;padding:10px 0;min-width:10rem;z-index:1500;position:fixed;list-style:none;box-sizing:border-box;max-height:calc(100% - 50px);overflow-y:auto}.v-context>li,.v-context ul>li{margin:0;position:relative}.v-context>li>a,.v-context ul>li>a{display:block;padding:.5rem 1.5rem;font-weight:400;color:#212529;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.v-context>li>a:focus,.v-context>li>a:hover,.v-context ul>li>a:focus,.v-context ul>li>a:hover{text-decoration:none;color:#212529;background-color:#f8f9fa}.v-context:focus,.v-context>li>a:focus,.v-context ul:focus,.v-context ul>li>a:focus{outline:0}.v-context__sub>a:after{content:"\2BC8";float:right;padding-left:1rem}.v-context__sub>ul{display:none}
|
||||
Vendored
-1
File diff suppressed because one or more lines are too long
+2
-3
@@ -2,13 +2,12 @@
|
||||
"name": "vue-context",
|
||||
"version": "4.1.1",
|
||||
"description": "A simple vue context menu component.",
|
||||
"main": "dist/js/vue-context.js",
|
||||
"main": "src/js/index.js",
|
||||
"scripts": {
|
||||
"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",
|
||||
"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-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",
|
||||
"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",
|
||||
"styles": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --env.mixfile=build/webpack-styles.mix.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
"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"
|
||||
},
|
||||
"keywords": [
|
||||
"Vue",
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export { default } from './vue-context';
|
||||
export { default as VueContext } from './vue-context';
|
||||
|
||||
+13
-1
@@ -17,7 +17,9 @@ export const isArray = Array.isArray;
|
||||
|
||||
export const keyCodes = {
|
||||
ESC: 27,
|
||||
LEFT: 37,
|
||||
UP: 38,
|
||||
RIGHT: 39,
|
||||
DOWN: 40
|
||||
};
|
||||
|
||||
@@ -51,7 +53,7 @@ export const filterVisible = elements => (elements || []).filter(isVisible);
|
||||
|
||||
// Return the Bounding Client Rect of an element
|
||||
// Returns `null` if not an element
|
||||
const getBCR = el => (isElement(el) ? el.getBoundingClientRect() : null);
|
||||
export const getBCR = el => (isElement(el) ? el.getBoundingClientRect() : null);
|
||||
|
||||
// Determine if an element is an HTML element
|
||||
const isElement = el => Boolean(el && el.nodeType === Node.ELEMENT_NODE);
|
||||
@@ -81,3 +83,13 @@ export const setAttr = (el, attr, value) => {
|
||||
el.setAttribute(attr, value);
|
||||
}
|
||||
};
|
||||
|
||||
export const parentElementByClassName = (element, className) => {
|
||||
let parentElement = element.parentElement;
|
||||
|
||||
while (parentElement !== null && !parentElement.classList.contains(className)) {
|
||||
parentElement = parentElement.parentElement;
|
||||
}
|
||||
|
||||
return parentElement;
|
||||
};
|
||||
|
||||
+119
-9
@@ -1,5 +1,15 @@
|
||||
import { directive as onClickaway } from 'vue-clickaway/index';
|
||||
import { eventOff, eventOn, filterVisible, isArray, keyCodes, selectAll, setAttr } from './utils';
|
||||
import {
|
||||
eventOff,
|
||||
eventOn,
|
||||
filterVisible,
|
||||
isArray,
|
||||
keyCodes,
|
||||
selectAll,
|
||||
setAttr,
|
||||
getBCR,
|
||||
parentElementByClassName
|
||||
} from './utils';
|
||||
import { normalizeSlot } from './normalize-slot';
|
||||
|
||||
export default {
|
||||
@@ -48,7 +58,8 @@ export default {
|
||||
left: null,
|
||||
show: false,
|
||||
data: null,
|
||||
localItemSelector: ''
|
||||
localItemSelector: '',
|
||||
activeSubMenu: null
|
||||
};
|
||||
},
|
||||
|
||||
@@ -67,12 +78,27 @@ export default {
|
||||
eventOn(window, 'scroll', this.close);
|
||||
},
|
||||
|
||||
addHoverEventListener(element) {
|
||||
element.querySelectorAll('.v-context__sub').forEach(
|
||||
subMenuNode => {
|
||||
eventOn(subMenuNode, 'mouseenter', this.openSubMenu);
|
||||
eventOn(subMenuNode, 'mouseleave', this.closeSubMenu);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
close() {
|
||||
if (! this.show) {
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure all sub menus are closed
|
||||
while (this.activeSubMenu !== null) {
|
||||
parentElementByClassName(this.activeSubMenu, 'v-context__sub').dispatchEvent(new Event('mouseleave'));
|
||||
}
|
||||
|
||||
this.resetData();
|
||||
this.removeHoverEventListener(this.$el);
|
||||
|
||||
if (this.closeOnScroll) {
|
||||
this.removeScrollEventListener();
|
||||
@@ -118,7 +144,8 @@ export default {
|
||||
},
|
||||
|
||||
getItems() {
|
||||
return filterVisible(selectAll(this.localItemSelector, this.$el));
|
||||
// if a sub menu is active only return the elements of the sub menu to keep the scope
|
||||
return filterVisible(selectAll(this.localItemSelector, this.activeSubMenu || this.$el));
|
||||
},
|
||||
|
||||
mapItemSelector(itemSelector) {
|
||||
@@ -147,6 +174,27 @@ export default {
|
||||
} else if (key === keyCodes.UP) {
|
||||
// Up arrow
|
||||
this.focusNext(event, true);
|
||||
} else if (key === keyCodes.RIGHT) {
|
||||
// check if a parent element which is associated with a sub menu can be found.
|
||||
const menuContainer = parentElementByClassName(event.target, 'v-context__sub');
|
||||
|
||||
// try to open a sub menu if the sub menu isn't the current sub menu
|
||||
if (menuContainer && menuContainer.getElementsByClassName('v-context')[0] !== this.activeSubMenu) {
|
||||
menuContainer.dispatchEvent(new Event('mouseenter'));
|
||||
this.focusNext(event, false);
|
||||
}
|
||||
} else if (key === keyCodes.LEFT) {
|
||||
if (!this.activeSubMenu) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parentMenu = parentElementByClassName(this.activeSubMenu, 'v-context__sub');
|
||||
parentMenu.dispatchEvent(new Event('mouseleave'));
|
||||
|
||||
const items = this.getItems(),
|
||||
index = items.indexOf(parentMenu.getElementsByTagName('a')[0]);
|
||||
|
||||
this.focusItem(index, items);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -155,9 +203,11 @@ export default {
|
||||
this.show = true;
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.positionMenu(event.clientY, event.clientX);
|
||||
[this.top, this.left] = this.positionMenu(event.clientY, event.clientX, this.$el);
|
||||
|
||||
this.$el.focus();
|
||||
this.setItemRoles();
|
||||
this.addHoverEventListener(this.$el);
|
||||
|
||||
if (this.closeOnScroll) {
|
||||
this.addScrollEventListener();
|
||||
@@ -167,9 +217,61 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
positionMenu(top, left) {
|
||||
const largestHeight = window.innerHeight - this.$el.offsetHeight - 25;
|
||||
const largestWidth = window.innerWidth - this.$el.offsetWidth - 25;
|
||||
openSubMenu(event) {
|
||||
const subMenuElement = this.getSubMenuElementByEvent(event),
|
||||
parentMenu = parentElementByClassName(subMenuElement.parentElement, 'v-context'),
|
||||
bcr = getBCR(event.target);
|
||||
|
||||
// check if another sub menu is open. In this case make sure no other as well as no nested sub menu is open
|
||||
if (this.activeSubMenu !== parentMenu) {
|
||||
while (this.activeSubMenu !== null
|
||||
&& this.activeSubMenu !== parentMenu
|
||||
&& this.activeSubMenu !== subMenuElement
|
||||
) {
|
||||
parentElementByClassName(this.activeSubMenu, 'v-context__sub')
|
||||
.dispatchEvent(new Event('mouseleave'));
|
||||
}
|
||||
}
|
||||
|
||||
// first set the display and afterwards execute position calculation for correct element offsets
|
||||
subMenuElement.style.display = 'block';
|
||||
|
||||
let [elementTop, elementLeft] = this.positionMenu(bcr.top, bcr.right - 10, subMenuElement);
|
||||
|
||||
subMenuElement.style.left = `${elementLeft}px`;
|
||||
subMenuElement.style.top = `${elementTop}px`;
|
||||
|
||||
this.activeSubMenu = subMenuElement;
|
||||
},
|
||||
|
||||
closeSubMenu(event) {
|
||||
const subMenuElement = this.getSubMenuElementByEvent(event),
|
||||
parentMenu = parentElementByClassName(subMenuElement, 'v-context');
|
||||
|
||||
// if a sub menu is closed and it's not the currently active sub menu (eg. a lowe layered sub menu closed
|
||||
// by a mouseleave event) close all nested sub menus
|
||||
if (this.activeSubMenu !== subMenuElement) {
|
||||
while (this.activeSubMenu !== null && this.activeSubMenu !== subMenuElement) {
|
||||
parentElementByClassName(this.activeSubMenu, 'v-context__sub')
|
||||
.dispatchEvent(new Event('mouseleave'));
|
||||
}
|
||||
}
|
||||
|
||||
subMenuElement.style.display = 'none';
|
||||
|
||||
// check if a parent menu exists and the parent menu is a sub menu to keep track of the correct sub menu
|
||||
this.activeSubMenu = parentMenu && parentElementByClassName(parentMenu, 'v-context__sub')
|
||||
? parentMenu
|
||||
: null;
|
||||
},
|
||||
|
||||
getSubMenuElementByEvent (event) {
|
||||
return event.target.getElementsByTagName('ul')[0];
|
||||
},
|
||||
|
||||
positionMenu(top, left, element) {
|
||||
const largestHeight = window.innerHeight - element.offsetHeight - 25;
|
||||
const largestWidth = window.innerWidth - element.offsetWidth - 25;
|
||||
|
||||
if (top > largestHeight) {
|
||||
top = largestHeight;
|
||||
@@ -179,14 +281,22 @@ export default {
|
||||
left = largestWidth;
|
||||
}
|
||||
|
||||
this.top = top;
|
||||
this.left = left;
|
||||
return [top, left];
|
||||
},
|
||||
|
||||
removeScrollEventListener() {
|
||||
eventOff(window, 'scroll', this.close);
|
||||
},
|
||||
|
||||
removeHoverEventListener(element) {
|
||||
element.querySelectorAll('.v-context__sub').forEach(
|
||||
(subMenuNode) => {
|
||||
eventOff(subMenuNode, 'mouseenter', this.openSubMenu);
|
||||
eventOff(subMenuNode, 'mouseleave', this.closeSubMenu);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
resetData() {
|
||||
this.top = null;
|
||||
this.left = null;
|
||||
|
||||
+50
-33
@@ -1,47 +1,64 @@
|
||||
@import "config";
|
||||
|
||||
.v-context {
|
||||
background-color: $menu-bg;
|
||||
background-clip: padding-box;
|
||||
border-radius: .25rem;
|
||||
border: 1px solid $menu-border;
|
||||
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: 10px 0;
|
||||
min-width: 10rem;
|
||||
z-index: 1500;
|
||||
position: fixed;
|
||||
list-style: none;
|
||||
box-sizing: border-box;
|
||||
|
||||
> li {
|
||||
&, & ul {
|
||||
background-color: $menu-bg;
|
||||
background-clip: padding-box;
|
||||
border-radius: .25rem;
|
||||
border: 1px solid $menu-border;
|
||||
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: 10px 0;
|
||||
min-width: 10rem;
|
||||
z-index: 1500;
|
||||
position: fixed;
|
||||
list-style: none;
|
||||
box-sizing: border-box;
|
||||
max-height: calc(100% - 50px);
|
||||
overflow-y: auto;
|
||||
|
||||
> a {
|
||||
display: block;
|
||||
padding: .5rem 1.5rem;
|
||||
font-weight: 400;
|
||||
color: $item-color;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
> li {
|
||||
margin: 0;
|
||||
position: relative;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
> a {
|
||||
display: block;
|
||||
padding: .5rem 1.5rem;
|
||||
font-weight: 400;
|
||||
color: $item-color;
|
||||
text-decoration: none;
|
||||
color: $item-hover-color;
|
||||
background-color: $item-hover-bg;
|
||||
}
|
||||
white-space: nowrap;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: none;
|
||||
color: $item-hover-color;
|
||||
background-color: $item-hover-bg;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
&__sub {
|
||||
> a:after {
|
||||
content: "\2bc8";
|
||||
float: right;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
> ul {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+58
-1
@@ -27,12 +27,69 @@
|
||||
Do something
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li class="v-context__sub">
|
||||
<a href="#" class="v-context-item"
|
||||
@click.prevent="onClick('item 2')"
|
||||
>
|
||||
Do something else
|
||||
</a>
|
||||
<ul class="v-context">
|
||||
<li tabindex="0">
|
||||
<a href="#" class="v-context-item"
|
||||
@click.prevent="onClick('sub item 1')"
|
||||
>
|
||||
Submenu
|
||||
</a>
|
||||
</li>
|
||||
<li class="v-context__sub">
|
||||
<a href="#" class="v-context-item"
|
||||
@click.prevent="onClick('sub item 2')"
|
||||
>
|
||||
Submenu next
|
||||
</a>
|
||||
|
||||
<ul class="v-context">
|
||||
<li tabindex="0">
|
||||
<a href="#" class="v-context-item"
|
||||
@click.prevent="onClick('sub sub item 1')"
|
||||
>
|
||||
We need to go deeper
|
||||
</a>
|
||||
</li>
|
||||
<li tabindex="0">
|
||||
<a href="#" class="v-context-item"
|
||||
@click.prevent="onClick('sub sub item 2')"
|
||||
>
|
||||
double nested Submenu
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="v-context-item"
|
||||
@click.prevent="onClick('sub item 3')"
|
||||
>
|
||||
Submenu next
|
||||
</a>
|
||||
</li>
|
||||
<li class="v-context__sub">
|
||||
<a href="#" class="v-context-item"
|
||||
@click.prevent="onClick('sub item 4')"
|
||||
>
|
||||
second nested Submenu
|
||||
</a>
|
||||
|
||||
<ul class="v-context">
|
||||
<li tabindex="0">
|
||||
<a href="#" class="v-context-item"
|
||||
@click.prevent="onClick('sub sub item 3')"
|
||||
>
|
||||
sub sub
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="v-context-item"
|
||||
|
||||
Vendored
-46
@@ -1,46 +0,0 @@
|
||||
.v-context {
|
||||
background-color: #fff;
|
||||
background-clip: padding-box;
|
||||
border-radius: 0.25rem;
|
||||
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||
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: 10px 0;
|
||||
min-width: 10rem;
|
||||
z-index: 1500;
|
||||
position: fixed;
|
||||
list-style: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.v-context > li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.v-context > li > a {
|
||||
display: block;
|
||||
padding: 0.5rem 1.5rem;
|
||||
font-weight: 400;
|
||||
color: #212529;
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.v-context > li > a:hover,
|
||||
.v-context > li > a:focus {
|
||||
text-decoration: none;
|
||||
color: #212529;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.v-context > li > a:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.v-context:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
Vendored
-214
File diff suppressed because one or more lines are too long
@@ -1,6 +1,5 @@
|
||||
import Vue from 'vue';
|
||||
// import { VueContext } from '../../../src/js/index';
|
||||
import { VueContext } from '../../../dist/js/vue-context';
|
||||
import VueContext from '../../../src/js/index';
|
||||
|
||||
new Vue({
|
||||
components: {
|
||||
|
||||
Reference in New Issue
Block a user